From: Reino Ruusu Date: Fri, 3 Mar 2017 11:16:25 +0000 (+0200) Subject: Three new projects for a Matlab integration feature. X-Git-Tag: v1.31.0~2 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=cc5c5889488f2fbbee837061177d25876b9ff860;p=simantics%2Fmatlab.git Three new projects for a Matlab integration feature. Change-Id: I27efcee2d6d5a8073a419af6ccd76343cbe3fb40 --- diff --git a/org.simantics.matlablink.feature/.project b/org.simantics.matlablink.feature/.project new file mode 100644 index 0000000..d348cac --- /dev/null +++ b/org.simantics.matlablink.feature/.project @@ -0,0 +1,17 @@ + + + org.simantics.matlablink.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/org.simantics.matlablink.feature/build.properties b/org.simantics.matlablink.feature/build.properties new file mode 100644 index 0000000..82ab19c --- /dev/null +++ b/org.simantics.matlablink.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/org.simantics.matlablink.feature/feature.xml b/org.simantics.matlablink.feature/feature.xml new file mode 100644 index 0000000..292ec4a --- /dev/null +++ b/org.simantics.matlablink.feature/feature.xml @@ -0,0 +1,42 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + + + + + + diff --git a/org.simantics.matlablink.win32.x86_64/.classpath b/org.simantics.matlablink.win32.x86_64/.classpath new file mode 100644 index 0000000..b862a29 --- /dev/null +++ b/org.simantics.matlablink.win32.x86_64/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.simantics.matlablink.win32.x86_64/.project b/org.simantics.matlablink.win32.x86_64/.project new file mode 100644 index 0000000..152bbee --- /dev/null +++ b/org.simantics.matlablink.win32.x86_64/.project @@ -0,0 +1,28 @@ + + + org.simantics.matlablink.win32.x86_64 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.simantics.matlablink.win32.x86_64/.settings/org.eclipse.jdt.core.prefs b/org.simantics.matlablink.win32.x86_64/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..295926d --- /dev/null +++ b/org.simantics.matlablink.win32.x86_64/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/org.simantics.matlablink.win32.x86_64/.settings/org.eclipse.pde.core.prefs b/org.simantics.matlablink.win32.x86_64/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 0000000..d711c29 --- /dev/null +++ b/org.simantics.matlablink.win32.x86_64/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +pluginProject.equinox=false +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/org.simantics.matlablink.win32.x86_64/META-INF/MANIFEST.MF b/org.simantics.matlablink.win32.x86_64/META-INF/MANIFEST.MF new file mode 100644 index 0000000..83b191a --- /dev/null +++ b/org.simantics.matlablink.win32.x86_64/META-INF/MANIFEST.MF @@ -0,0 +1,7 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: org.simantics.matlablink.win32.x86_64 +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: VTT Technical Research Centre of Finland +Fragment-Host: org.simantics.matlablink;bundle-version="1.0.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/org.simantics.matlablink.win32.x86_64/bin/.gitignore b/org.simantics.matlablink.win32.x86_64/bin/.gitignore new file mode 100644 index 0000000..2fc9e08 --- /dev/null +++ b/org.simantics.matlablink.win32.x86_64/bin/.gitignore @@ -0,0 +1,6 @@ +/jni.h +/jni_md.h +/jnimatlab.vcxproj +/jnimatlab.vcxproj.filters +/sclmat.c +/sclmat.h diff --git a/org.simantics.matlablink.win32.x86_64/build.properties b/org.simantics.matlablink.win32.x86_64/build.properties new file mode 100644 index 0000000..2d0d26e --- /dev/null +++ b/org.simantics.matlablink.win32.x86_64/build.properties @@ -0,0 +1,8 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + jnimatlab.dll,\ + jnipython.dll +src.includes = jnimatlab.dll,\ + jnipython.dll diff --git a/org.simantics.matlablink.win32.x86_64/jnimatlab.dll b/org.simantics.matlablink.win32.x86_64/jnimatlab.dll new file mode 100644 index 0000000..fbacece Binary files /dev/null and b/org.simantics.matlablink.win32.x86_64/jnimatlab.dll differ diff --git a/org.simantics.matlablink.win32.x86_64/src/jni.h b/org.simantics.matlablink.win32.x86_64/src/jni.h new file mode 100644 index 0000000..f53476c --- /dev/null +++ b/org.simantics.matlablink.win32.x86_64/src/jni.h @@ -0,0 +1,1944 @@ +/* + * @(#)jni.h 1.62 06/02/02 + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +/* + * We used part of Netscape's Java Runtime Interface (JRI) as the starting + * point of our design and implementation. + */ + +/****************************************************************************** + * Java Runtime Interface + * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. + *****************************************************************************/ + +#ifndef _JAVASOFT_JNI_H_ +#define _JAVASOFT_JNI_H_ + +#include +#include + +/* jni_md.h contains the machine-dependent typedefs for jbyte, jint + and jlong */ + +#include "jni_md.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * JNI Types + */ + +#ifndef JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H + +typedef unsigned char jboolean; +typedef unsigned short jchar; +typedef short jshort; +typedef float jfloat; +typedef double jdouble; + +typedef jint jsize; + +#ifdef __cplusplus + +class _jobject {}; +class _jclass : public _jobject {}; +class _jthrowable : public _jobject {}; +class _jstring : public _jobject {}; +class _jarray : public _jobject {}; +class _jbooleanArray : public _jarray {}; +class _jbyteArray : public _jarray {}; +class _jcharArray : public _jarray {}; +class _jshortArray : public _jarray {}; +class _jintArray : public _jarray {}; +class _jlongArray : public _jarray {}; +class _jfloatArray : public _jarray {}; +class _jdoubleArray : public _jarray {}; +class _jobjectArray : public _jarray {}; + +typedef _jobject *jobject; +typedef _jclass *jclass; +typedef _jthrowable *jthrowable; +typedef _jstring *jstring; +typedef _jarray *jarray; +typedef _jbooleanArray *jbooleanArray; +typedef _jbyteArray *jbyteArray; +typedef _jcharArray *jcharArray; +typedef _jshortArray *jshortArray; +typedef _jintArray *jintArray; +typedef _jlongArray *jlongArray; +typedef _jfloatArray *jfloatArray; +typedef _jdoubleArray *jdoubleArray; +typedef _jobjectArray *jobjectArray; + +#else + +struct _jobject; + +typedef struct _jobject *jobject; +typedef jobject jclass; +typedef jobject jthrowable; +typedef jobject jstring; +typedef jobject jarray; +typedef jarray jbooleanArray; +typedef jarray jbyteArray; +typedef jarray jcharArray; +typedef jarray jshortArray; +typedef jarray jintArray; +typedef jarray jlongArray; +typedef jarray jfloatArray; +typedef jarray jdoubleArray; +typedef jarray jobjectArray; + +#endif + +typedef jobject jweak; + +typedef union jvalue { + jboolean z; + jbyte b; + jchar c; + jshort s; + jint i; + jlong j; + jfloat f; + jdouble d; + jobject l; +} jvalue; + +struct _jfieldID; +typedef struct _jfieldID *jfieldID; + +struct _jmethodID; +typedef struct _jmethodID *jmethodID; + +/* Return values from jobjectRefType */ +typedef enum _jobjectType { + JNIInvalidRefType = 0, + JNILocalRefType = 1, + JNIGlobalRefType = 2, + JNIWeakGlobalRefType = 3 +} jobjectRefType; + + +#endif /* JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H */ + +/* + * jboolean constants + */ + +#define JNI_FALSE 0 +#define JNI_TRUE 1 + +/* + * possible return values for JNI functions. + */ + +#define JNI_OK 0 /* success */ +#define JNI_ERR (-1) /* unknown error */ +#define JNI_EDETACHED (-2) /* thread detached from the VM */ +#define JNI_EVERSION (-3) /* JNI version error */ +#define JNI_ENOMEM (-4) /* not enough memory */ +#define JNI_EEXIST (-5) /* VM already created */ +#define JNI_EINVAL (-6) /* invalid arguments */ + +/* + * used in ReleaseScalarArrayElements + */ + +#define JNI_COMMIT 1 +#define JNI_ABORT 2 + +/* + * used in RegisterNatives to describe native method name, signature, + * and function pointer. + */ + +typedef struct { + char *name; + char *signature; + void *fnPtr; +} JNINativeMethod; + +/* + * JNI Native Method Interface. + */ + +struct JNINativeInterface_; + +struct JNIEnv_; + +#ifdef __cplusplus +typedef JNIEnv_ JNIEnv; +#else +typedef const struct JNINativeInterface_ *JNIEnv; +#endif + +/* + * JNI Invocation Interface. + */ + +struct JNIInvokeInterface_; + +struct JavaVM_; + +#ifdef __cplusplus +typedef JavaVM_ JavaVM; +#else +typedef const struct JNIInvokeInterface_ *JavaVM; +#endif + +struct JNINativeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + void *reserved3; + jint (JNICALL *GetVersion)(JNIEnv *env); + + jclass (JNICALL *DefineClass) + (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, + jsize len); + jclass (JNICALL *FindClass) + (JNIEnv *env, const char *name); + + jmethodID (JNICALL *FromReflectedMethod) + (JNIEnv *env, jobject method); + jfieldID (JNICALL *FromReflectedField) + (JNIEnv *env, jobject field); + + jobject (JNICALL *ToReflectedMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic); + + jclass (JNICALL *GetSuperclass) + (JNIEnv *env, jclass sub); + jboolean (JNICALL *IsAssignableFrom) + (JNIEnv *env, jclass sub, jclass sup); + + jobject (JNICALL *ToReflectedField) + (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic); + + jint (JNICALL *Throw) + (JNIEnv *env, jthrowable obj); + jint (JNICALL *ThrowNew) + (JNIEnv *env, jclass clazz, const char *msg); + jthrowable (JNICALL *ExceptionOccurred) + (JNIEnv *env); + void (JNICALL *ExceptionDescribe) + (JNIEnv *env); + void (JNICALL *ExceptionClear) + (JNIEnv *env); + void (JNICALL *FatalError) + (JNIEnv *env, const char *msg); + + jint (JNICALL *PushLocalFrame) + (JNIEnv *env, jint capacity); + jobject (JNICALL *PopLocalFrame) + (JNIEnv *env, jobject result); + + jobject (JNICALL *NewGlobalRef) + (JNIEnv *env, jobject lobj); + void (JNICALL *DeleteGlobalRef) + (JNIEnv *env, jobject gref); + void (JNICALL *DeleteLocalRef) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsSameObject) + (JNIEnv *env, jobject obj1, jobject obj2); + jobject (JNICALL *NewLocalRef) + (JNIEnv *env, jobject ref); + jint (JNICALL *EnsureLocalCapacity) + (JNIEnv *env, jint capacity); + + jobject (JNICALL *AllocObject) + (JNIEnv *env, jclass clazz); + jobject (JNICALL *NewObject) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *NewObjectV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *NewObjectA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jclass (JNICALL *GetObjectClass) + (JNIEnv *env, jobject obj); + jboolean (JNICALL *IsInstanceOf) + (JNIEnv *env, jobject obj, jclass clazz); + + jmethodID (JNICALL *GetMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallObjectMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jobject (JNICALL *CallObjectMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jobject (JNICALL *CallObjectMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jboolean (JNICALL *CallBooleanMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jboolean (JNICALL *CallBooleanMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jboolean (JNICALL *CallBooleanMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jbyte (JNICALL *CallByteMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jbyte (JNICALL *CallByteMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jbyte (JNICALL *CallByteMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallCharMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jchar (JNICALL *CallCharMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jchar (JNICALL *CallCharMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallShortMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jshort (JNICALL *CallShortMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jshort (JNICALL *CallShortMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallIntMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jint (JNICALL *CallIntMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jint (JNICALL *CallIntMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallLongMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jlong (JNICALL *CallLongMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jlong (JNICALL *CallLongMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallFloatMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jfloat (JNICALL *CallFloatMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jfloat (JNICALL *CallFloatMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallDoubleMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + jdouble (JNICALL *CallDoubleMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + jdouble (JNICALL *CallDoubleMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallVoidMethod) + (JNIEnv *env, jobject obj, jmethodID methodID, ...); + void (JNICALL *CallVoidMethodV) + (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); + void (JNICALL *CallVoidMethodA) + (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); + + jobject (JNICALL *CallNonvirtualObjectMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallNonvirtualObjectMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jobject (JNICALL *CallNonvirtualObjectMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jboolean (JNICALL *CallNonvirtualBooleanMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallNonvirtualBooleanMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jboolean (JNICALL *CallNonvirtualBooleanMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jbyte (JNICALL *CallNonvirtualByteMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallNonvirtualByteMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jbyte (JNICALL *CallNonvirtualByteMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jchar (JNICALL *CallNonvirtualCharMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallNonvirtualCharMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jchar (JNICALL *CallNonvirtualCharMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jshort (JNICALL *CallNonvirtualShortMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallNonvirtualShortMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jshort (JNICALL *CallNonvirtualShortMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jint (JNICALL *CallNonvirtualIntMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallNonvirtualIntMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jint (JNICALL *CallNonvirtualIntMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jlong (JNICALL *CallNonvirtualLongMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallNonvirtualLongMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jlong (JNICALL *CallNonvirtualLongMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jfloat (JNICALL *CallNonvirtualFloatMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallNonvirtualFloatMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jfloat (JNICALL *CallNonvirtualFloatMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + jdouble (JNICALL *CallNonvirtualDoubleMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallNonvirtualDoubleMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + jdouble (JNICALL *CallNonvirtualDoubleMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue *args); + + void (JNICALL *CallNonvirtualVoidMethod) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); + void (JNICALL *CallNonvirtualVoidMethodV) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + va_list args); + void (JNICALL *CallNonvirtualVoidMethodA) + (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, + const jvalue * args); + + jfieldID (JNICALL *GetFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *GetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jboolean (JNICALL *GetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jbyte (JNICALL *GetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jchar (JNICALL *GetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jshort (JNICALL *GetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jint (JNICALL *GetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jlong (JNICALL *GetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jfloat (JNICALL *GetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + jdouble (JNICALL *GetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID); + + void (JNICALL *SetObjectField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val); + void (JNICALL *SetBooleanField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val); + void (JNICALL *SetByteField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val); + void (JNICALL *SetCharField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val); + void (JNICALL *SetShortField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val); + void (JNICALL *SetIntField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jint val); + void (JNICALL *SetLongField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val); + void (JNICALL *SetFloatField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val); + void (JNICALL *SetDoubleField) + (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val); + + jmethodID (JNICALL *GetStaticMethodID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + + jobject (JNICALL *CallStaticObjectMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jobject (JNICALL *CallStaticObjectMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jobject (JNICALL *CallStaticObjectMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jboolean (JNICALL *CallStaticBooleanMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jboolean (JNICALL *CallStaticBooleanMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jboolean (JNICALL *CallStaticBooleanMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jbyte (JNICALL *CallStaticByteMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jbyte (JNICALL *CallStaticByteMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jbyte (JNICALL *CallStaticByteMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jchar (JNICALL *CallStaticCharMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jchar (JNICALL *CallStaticCharMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jchar (JNICALL *CallStaticCharMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jshort (JNICALL *CallStaticShortMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jshort (JNICALL *CallStaticShortMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jshort (JNICALL *CallStaticShortMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jint (JNICALL *CallStaticIntMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jint (JNICALL *CallStaticIntMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jint (JNICALL *CallStaticIntMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jlong (JNICALL *CallStaticLongMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jlong (JNICALL *CallStaticLongMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jlong (JNICALL *CallStaticLongMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jfloat (JNICALL *CallStaticFloatMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jfloat (JNICALL *CallStaticFloatMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jfloat (JNICALL *CallStaticFloatMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + jdouble (JNICALL *CallStaticDoubleMethod) + (JNIEnv *env, jclass clazz, jmethodID methodID, ...); + jdouble (JNICALL *CallStaticDoubleMethodV) + (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); + jdouble (JNICALL *CallStaticDoubleMethodA) + (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); + + void (JNICALL *CallStaticVoidMethod) + (JNIEnv *env, jclass cls, jmethodID methodID, ...); + void (JNICALL *CallStaticVoidMethodV) + (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); + void (JNICALL *CallStaticVoidMethodA) + (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args); + + jfieldID (JNICALL *GetStaticFieldID) + (JNIEnv *env, jclass clazz, const char *name, const char *sig); + jobject (JNICALL *GetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jboolean (JNICALL *GetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jbyte (JNICALL *GetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jchar (JNICALL *GetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jshort (JNICALL *GetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jint (JNICALL *GetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jlong (JNICALL *GetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jfloat (JNICALL *GetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + jdouble (JNICALL *GetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID); + + void (JNICALL *SetStaticObjectField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value); + void (JNICALL *SetStaticBooleanField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value); + void (JNICALL *SetStaticByteField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value); + void (JNICALL *SetStaticCharField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value); + void (JNICALL *SetStaticShortField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value); + void (JNICALL *SetStaticIntField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value); + void (JNICALL *SetStaticLongField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value); + void (JNICALL *SetStaticFloatField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value); + void (JNICALL *SetStaticDoubleField) + (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value); + + jstring (JNICALL *NewString) + (JNIEnv *env, const jchar *unicode, jsize len); + jsize (JNICALL *GetStringLength) + (JNIEnv *env, jstring str); + const jchar *(JNICALL *GetStringChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringChars) + (JNIEnv *env, jstring str, const jchar *chars); + + jstring (JNICALL *NewStringUTF) + (JNIEnv *env, const char *utf); + jsize (JNICALL *GetStringUTFLength) + (JNIEnv *env, jstring str); + const char* (JNICALL *GetStringUTFChars) + (JNIEnv *env, jstring str, jboolean *isCopy); + void (JNICALL *ReleaseStringUTFChars) + (JNIEnv *env, jstring str, const char* chars); + + + jsize (JNICALL *GetArrayLength) + (JNIEnv *env, jarray array); + + jobjectArray (JNICALL *NewObjectArray) + (JNIEnv *env, jsize len, jclass clazz, jobject init); + jobject (JNICALL *GetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index); + void (JNICALL *SetObjectArrayElement) + (JNIEnv *env, jobjectArray array, jsize index, jobject val); + + jbooleanArray (JNICALL *NewBooleanArray) + (JNIEnv *env, jsize len); + jbyteArray (JNICALL *NewByteArray) + (JNIEnv *env, jsize len); + jcharArray (JNICALL *NewCharArray) + (JNIEnv *env, jsize len); + jshortArray (JNICALL *NewShortArray) + (JNIEnv *env, jsize len); + jintArray (JNICALL *NewIntArray) + (JNIEnv *env, jsize len); + jlongArray (JNICALL *NewLongArray) + (JNIEnv *env, jsize len); + jfloatArray (JNICALL *NewFloatArray) + (JNIEnv *env, jsize len); + jdoubleArray (JNICALL *NewDoubleArray) + (JNIEnv *env, jsize len); + + jboolean * (JNICALL *GetBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *isCopy); + jbyte * (JNICALL *GetByteArrayElements) + (JNIEnv *env, jbyteArray array, jboolean *isCopy); + jchar * (JNICALL *GetCharArrayElements) + (JNIEnv *env, jcharArray array, jboolean *isCopy); + jshort * (JNICALL *GetShortArrayElements) + (JNIEnv *env, jshortArray array, jboolean *isCopy); + jint * (JNICALL *GetIntArrayElements) + (JNIEnv *env, jintArray array, jboolean *isCopy); + jlong * (JNICALL *GetLongArrayElements) + (JNIEnv *env, jlongArray array, jboolean *isCopy); + jfloat * (JNICALL *GetFloatArrayElements) + (JNIEnv *env, jfloatArray array, jboolean *isCopy); + jdouble * (JNICALL *GetDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jboolean *isCopy); + + void (JNICALL *ReleaseBooleanArrayElements) + (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode); + void (JNICALL *ReleaseByteArrayElements) + (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode); + void (JNICALL *ReleaseCharArrayElements) + (JNIEnv *env, jcharArray array, jchar *elems, jint mode); + void (JNICALL *ReleaseShortArrayElements) + (JNIEnv *env, jshortArray array, jshort *elems, jint mode); + void (JNICALL *ReleaseIntArrayElements) + (JNIEnv *env, jintArray array, jint *elems, jint mode); + void (JNICALL *ReleaseLongArrayElements) + (JNIEnv *env, jlongArray array, jlong *elems, jint mode); + void (JNICALL *ReleaseFloatArrayElements) + (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode); + void (JNICALL *ReleaseDoubleArrayElements) + (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode); + + void (JNICALL *GetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); + void (JNICALL *GetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); + void (JNICALL *GetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); + void (JNICALL *GetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); + void (JNICALL *GetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); + void (JNICALL *GetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); + void (JNICALL *GetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); + void (JNICALL *GetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); + + void (JNICALL *SetBooleanArrayRegion) + (JNIEnv *env, jbooleanArray array, jsize start, jsize l, const jboolean *buf); + void (JNICALL *SetByteArrayRegion) + (JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf); + void (JNICALL *SetCharArrayRegion) + (JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf); + void (JNICALL *SetShortArrayRegion) + (JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf); + void (JNICALL *SetIntArrayRegion) + (JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf); + void (JNICALL *SetLongArrayRegion) + (JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf); + void (JNICALL *SetFloatArrayRegion) + (JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf); + void (JNICALL *SetDoubleArrayRegion) + (JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf); + + jint (JNICALL *RegisterNatives) + (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, + jint nMethods); + jint (JNICALL *UnregisterNatives) + (JNIEnv *env, jclass clazz); + + jint (JNICALL *MonitorEnter) + (JNIEnv *env, jobject obj); + jint (JNICALL *MonitorExit) + (JNIEnv *env, jobject obj); + + jint (JNICALL *GetJavaVM) + (JNIEnv *env, JavaVM **vm); + + void (JNICALL *GetStringRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf); + void (JNICALL *GetStringUTFRegion) + (JNIEnv *env, jstring str, jsize start, jsize len, char *buf); + + void * (JNICALL *GetPrimitiveArrayCritical) + (JNIEnv *env, jarray array, jboolean *isCopy); + void (JNICALL *ReleasePrimitiveArrayCritical) + (JNIEnv *env, jarray array, void *carray, jint mode); + + const jchar * (JNICALL *GetStringCritical) + (JNIEnv *env, jstring string, jboolean *isCopy); + void (JNICALL *ReleaseStringCritical) + (JNIEnv *env, jstring string, const jchar *cstring); + + jweak (JNICALL *NewWeakGlobalRef) + (JNIEnv *env, jobject obj); + void (JNICALL *DeleteWeakGlobalRef) + (JNIEnv *env, jweak ref); + + jboolean (JNICALL *ExceptionCheck) + (JNIEnv *env); + + jobject (JNICALL *NewDirectByteBuffer) + (JNIEnv* env, void* address, jlong capacity); + void* (JNICALL *GetDirectBufferAddress) + (JNIEnv* env, jobject buf); + jlong (JNICALL *GetDirectBufferCapacity) + (JNIEnv* env, jobject buf); + + /* New JNI 1.6 Features */ + + jobjectRefType (JNICALL *GetObjectRefType) + (JNIEnv* env, jobject obj); +}; + +/* + * We use inlined functions for C++ so that programmers can write: + * + * env->FindClass("java/lang/String") + * + * in C++ rather than: + * + * (*env)->FindClass(env, "java/lang/String") + * + * in C. + */ + +struct JNIEnv_ { + const struct JNINativeInterface_ *functions; +#ifdef __cplusplus + + jint GetVersion() { + return functions->GetVersion(this); + } + jclass DefineClass(const char *name, jobject loader, const jbyte *buf, + jsize len) { + return functions->DefineClass(this, name, loader, buf, len); + } + jclass FindClass(const char *name) { + return functions->FindClass(this, name); + } + jmethodID FromReflectedMethod(jobject method) { + return functions->FromReflectedMethod(this,method); + } + jfieldID FromReflectedField(jobject field) { + return functions->FromReflectedField(this,field); + } + + jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) { + return functions->ToReflectedMethod(this, cls, methodID, isStatic); + } + + jclass GetSuperclass(jclass sub) { + return functions->GetSuperclass(this, sub); + } + jboolean IsAssignableFrom(jclass sub, jclass sup) { + return functions->IsAssignableFrom(this, sub, sup); + } + + jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) { + return functions->ToReflectedField(this,cls,fieldID,isStatic); + } + + jint Throw(jthrowable obj) { + return functions->Throw(this, obj); + } + jint ThrowNew(jclass clazz, const char *msg) { + return functions->ThrowNew(this, clazz, msg); + } + jthrowable ExceptionOccurred() { + return functions->ExceptionOccurred(this); + } + void ExceptionDescribe() { + functions->ExceptionDescribe(this); + } + void ExceptionClear() { + functions->ExceptionClear(this); + } + void FatalError(const char *msg) { + functions->FatalError(this, msg); + } + + jint PushLocalFrame(jint capacity) { + return functions->PushLocalFrame(this,capacity); + } + jobject PopLocalFrame(jobject result) { + return functions->PopLocalFrame(this,result); + } + + jobject NewGlobalRef(jobject lobj) { + return functions->NewGlobalRef(this,lobj); + } + void DeleteGlobalRef(jobject gref) { + functions->DeleteGlobalRef(this,gref); + } + void DeleteLocalRef(jobject obj) { + functions->DeleteLocalRef(this, obj); + } + + jboolean IsSameObject(jobject obj1, jobject obj2) { + return functions->IsSameObject(this,obj1,obj2); + } + + jobject NewLocalRef(jobject ref) { + return functions->NewLocalRef(this,ref); + } + jint EnsureLocalCapacity(jint capacity) { + return functions->EnsureLocalCapacity(this,capacity); + } + + jobject AllocObject(jclass clazz) { + return functions->AllocObject(this,clazz); + } + jobject NewObject(jclass clazz, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args, methodID); + result = functions->NewObjectV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject NewObjectV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->NewObjectV(this,clazz,methodID,args); + } + jobject NewObjectA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->NewObjectA(this,clazz,methodID,args); + } + + jclass GetObjectClass(jobject obj) { + return functions->GetObjectClass(this,obj); + } + jboolean IsInstanceOf(jobject obj, jclass clazz) { + return functions->IsInstanceOf(this,obj,clazz); + } + + jmethodID GetMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetMethodID(this,clazz,name,sig); + } + + jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallObjectMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jobject CallObjectMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallObjectMethodV(this,obj,methodID,args); + } + jobject CallObjectMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallObjectMethodA(this,obj,methodID,args); + } + + jboolean CallBooleanMethod(jobject obj, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallBooleanMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jboolean CallBooleanMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallBooleanMethodV(this,obj,methodID,args); + } + jboolean CallBooleanMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallBooleanMethodA(this,obj,methodID, args); + } + + jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallByteMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jbyte CallByteMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallByteMethodV(this,obj,methodID,args); + } + jbyte CallByteMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallByteMethodA(this,obj,methodID,args); + } + + jchar CallCharMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallCharMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jchar CallCharMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallCharMethodV(this,obj,methodID,args); + } + jchar CallCharMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallCharMethodA(this,obj,methodID,args); + } + + jshort CallShortMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallShortMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jshort CallShortMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallShortMethodV(this,obj,methodID,args); + } + jshort CallShortMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallShortMethodA(this,obj,methodID,args); + } + + jint CallIntMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallIntMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jint CallIntMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallIntMethodV(this,obj,methodID,args); + } + jint CallIntMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallIntMethodA(this,obj,methodID,args); + } + + jlong CallLongMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallLongMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jlong CallLongMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallLongMethodV(this,obj,methodID,args); + } + jlong CallLongMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallLongMethodA(this,obj,methodID,args); + } + + jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallFloatMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jfloat CallFloatMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallFloatMethodV(this,obj,methodID,args); + } + jfloat CallFloatMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallFloatMethodA(this,obj,methodID,args); + } + + jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallDoubleMethodV(this,obj,methodID,args); + va_end(args); + return result; + } + jdouble CallDoubleMethodV(jobject obj, jmethodID methodID, + va_list args) { + return functions->CallDoubleMethodV(this,obj,methodID,args); + } + jdouble CallDoubleMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + return functions->CallDoubleMethodA(this,obj,methodID,args); + } + + void CallVoidMethod(jobject obj, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallVoidMethodV(this,obj,methodID,args); + va_end(args); + } + void CallVoidMethodV(jobject obj, jmethodID methodID, + va_list args) { + functions->CallVoidMethodV(this,obj,methodID,args); + } + void CallVoidMethodA(jobject obj, jmethodID methodID, + const jvalue * args) { + functions->CallVoidMethodA(this,obj,methodID,args); + } + + jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualObjectMethodV(this,obj,clazz, + methodID,args); + } + jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualObjectMethodA(this,obj,clazz, + methodID,args); + } + + jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualBooleanMethodV(this,obj,clazz, + methodID,args); + } + jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualBooleanMethodA(this,obj,clazz, + methodID, args); + } + + jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualByteMethodV(this,obj,clazz, + methodID,args); + } + jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualByteMethodA(this,obj,clazz, + methodID,args); + } + + jchar CallNonvirtualCharMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualCharMethodV(this,obj,clazz, + methodID,args); + } + jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualCharMethodA(this,obj,clazz, + methodID,args); + } + + jshort CallNonvirtualShortMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualShortMethodV(this,obj,clazz, + methodID,args); + } + jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualShortMethodA(this,obj,clazz, + methodID,args); + } + + jint CallNonvirtualIntMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jint CallNonvirtualIntMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualIntMethodV(this,obj,clazz, + methodID,args); + } + jint CallNonvirtualIntMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualIntMethodA(this,obj,clazz, + methodID,args); + } + + jlong CallNonvirtualLongMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallNonvirtualLongMethodV(this,obj,clazz, + methodID,args); + } + jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz, + jmethodID methodID, const jvalue * args) { + return functions->CallNonvirtualLongMethodA(this,obj,clazz, + methodID,args); + } + + jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualFloatMethodV(this,obj,clazz, + methodID,args); + } + jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualFloatMethodA(this,obj,clazz, + methodID,args); + } + + jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + va_end(args); + return result; + } + jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + return functions->CallNonvirtualDoubleMethodV(this,obj,clazz, + methodID,args); + } + jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + return functions->CallNonvirtualDoubleMethodA(this,obj,clazz, + methodID,args); + } + + void CallNonvirtualVoidMethod(jobject obj, jclass clazz, + jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + va_end(args); + } + void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, + jmethodID methodID, + va_list args) { + functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); + } + void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, + jmethodID methodID, + const jvalue * args) { + functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args); + } + + jfieldID GetFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetFieldID(this,clazz,name,sig); + } + + jobject GetObjectField(jobject obj, jfieldID fieldID) { + return functions->GetObjectField(this,obj,fieldID); + } + jboolean GetBooleanField(jobject obj, jfieldID fieldID) { + return functions->GetBooleanField(this,obj,fieldID); + } + jbyte GetByteField(jobject obj, jfieldID fieldID) { + return functions->GetByteField(this,obj,fieldID); + } + jchar GetCharField(jobject obj, jfieldID fieldID) { + return functions->GetCharField(this,obj,fieldID); + } + jshort GetShortField(jobject obj, jfieldID fieldID) { + return functions->GetShortField(this,obj,fieldID); + } + jint GetIntField(jobject obj, jfieldID fieldID) { + return functions->GetIntField(this,obj,fieldID); + } + jlong GetLongField(jobject obj, jfieldID fieldID) { + return functions->GetLongField(this,obj,fieldID); + } + jfloat GetFloatField(jobject obj, jfieldID fieldID) { + return functions->GetFloatField(this,obj,fieldID); + } + jdouble GetDoubleField(jobject obj, jfieldID fieldID) { + return functions->GetDoubleField(this,obj,fieldID); + } + + void SetObjectField(jobject obj, jfieldID fieldID, jobject val) { + functions->SetObjectField(this,obj,fieldID,val); + } + void SetBooleanField(jobject obj, jfieldID fieldID, + jboolean val) { + functions->SetBooleanField(this,obj,fieldID,val); + } + void SetByteField(jobject obj, jfieldID fieldID, + jbyte val) { + functions->SetByteField(this,obj,fieldID,val); + } + void SetCharField(jobject obj, jfieldID fieldID, + jchar val) { + functions->SetCharField(this,obj,fieldID,val); + } + void SetShortField(jobject obj, jfieldID fieldID, + jshort val) { + functions->SetShortField(this,obj,fieldID,val); + } + void SetIntField(jobject obj, jfieldID fieldID, + jint val) { + functions->SetIntField(this,obj,fieldID,val); + } + void SetLongField(jobject obj, jfieldID fieldID, + jlong val) { + functions->SetLongField(this,obj,fieldID,val); + } + void SetFloatField(jobject obj, jfieldID fieldID, + jfloat val) { + functions->SetFloatField(this,obj,fieldID,val); + } + void SetDoubleField(jobject obj, jfieldID fieldID, + jdouble val) { + functions->SetDoubleField(this,obj,fieldID,val); + } + + jmethodID GetStaticMethodID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticMethodID(this,clazz,name,sig); + } + + jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID, + ...) { + va_list args; + jobject result; + va_start(args,methodID); + result = functions->CallStaticObjectMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID, + va_list args) { + return functions->CallStaticObjectMethodV(this,clazz,methodID,args); + } + jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID, + const jvalue *args) { + return functions->CallStaticObjectMethodA(this,clazz,methodID,args); + } + + jboolean CallStaticBooleanMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jboolean result; + va_start(args,methodID); + result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jboolean CallStaticBooleanMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticBooleanMethodV(this,clazz,methodID,args); + } + jboolean CallStaticBooleanMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticBooleanMethodA(this,clazz,methodID,args); + } + + jbyte CallStaticByteMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jbyte result; + va_start(args,methodID); + result = functions->CallStaticByteMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jbyte CallStaticByteMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticByteMethodV(this,clazz,methodID,args); + } + jbyte CallStaticByteMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticByteMethodA(this,clazz,methodID,args); + } + + jchar CallStaticCharMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jchar result; + va_start(args,methodID); + result = functions->CallStaticCharMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jchar CallStaticCharMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticCharMethodV(this,clazz,methodID,args); + } + jchar CallStaticCharMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticCharMethodA(this,clazz,methodID,args); + } + + jshort CallStaticShortMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jshort result; + va_start(args,methodID); + result = functions->CallStaticShortMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jshort CallStaticShortMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticShortMethodV(this,clazz,methodID,args); + } + jshort CallStaticShortMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticShortMethodA(this,clazz,methodID,args); + } + + jint CallStaticIntMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jint result; + va_start(args,methodID); + result = functions->CallStaticIntMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jint CallStaticIntMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticIntMethodV(this,clazz,methodID,args); + } + jint CallStaticIntMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticIntMethodA(this,clazz,methodID,args); + } + + jlong CallStaticLongMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jlong result; + va_start(args,methodID); + result = functions->CallStaticLongMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jlong CallStaticLongMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticLongMethodV(this,clazz,methodID,args); + } + jlong CallStaticLongMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticLongMethodA(this,clazz,methodID,args); + } + + jfloat CallStaticFloatMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jfloat result; + va_start(args,methodID); + result = functions->CallStaticFloatMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jfloat CallStaticFloatMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticFloatMethodV(this,clazz,methodID,args); + } + jfloat CallStaticFloatMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticFloatMethodA(this,clazz,methodID,args); + } + + jdouble CallStaticDoubleMethod(jclass clazz, + jmethodID methodID, ...) { + va_list args; + jdouble result; + va_start(args,methodID); + result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + va_end(args); + return result; + } + jdouble CallStaticDoubleMethodV(jclass clazz, + jmethodID methodID, va_list args) { + return functions->CallStaticDoubleMethodV(this,clazz,methodID,args); + } + jdouble CallStaticDoubleMethodA(jclass clazz, + jmethodID methodID, const jvalue *args) { + return functions->CallStaticDoubleMethodA(this,clazz,methodID,args); + } + + void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) { + va_list args; + va_start(args,methodID); + functions->CallStaticVoidMethodV(this,cls,methodID,args); + va_end(args); + } + void CallStaticVoidMethodV(jclass cls, jmethodID methodID, + va_list args) { + functions->CallStaticVoidMethodV(this,cls,methodID,args); + } + void CallStaticVoidMethodA(jclass cls, jmethodID methodID, + const jvalue * args) { + functions->CallStaticVoidMethodA(this,cls,methodID,args); + } + + jfieldID GetStaticFieldID(jclass clazz, const char *name, + const char *sig) { + return functions->GetStaticFieldID(this,clazz,name,sig); + } + jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticObjectField(this,clazz,fieldID); + } + jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticBooleanField(this,clazz,fieldID); + } + jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticByteField(this,clazz,fieldID); + } + jchar GetStaticCharField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticCharField(this,clazz,fieldID); + } + jshort GetStaticShortField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticShortField(this,clazz,fieldID); + } + jint GetStaticIntField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticIntField(this,clazz,fieldID); + } + jlong GetStaticLongField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticLongField(this,clazz,fieldID); + } + jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticFloatField(this,clazz,fieldID); + } + jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) { + return functions->GetStaticDoubleField(this,clazz,fieldID); + } + + void SetStaticObjectField(jclass clazz, jfieldID fieldID, + jobject value) { + functions->SetStaticObjectField(this,clazz,fieldID,value); + } + void SetStaticBooleanField(jclass clazz, jfieldID fieldID, + jboolean value) { + functions->SetStaticBooleanField(this,clazz,fieldID,value); + } + void SetStaticByteField(jclass clazz, jfieldID fieldID, + jbyte value) { + functions->SetStaticByteField(this,clazz,fieldID,value); + } + void SetStaticCharField(jclass clazz, jfieldID fieldID, + jchar value) { + functions->SetStaticCharField(this,clazz,fieldID,value); + } + void SetStaticShortField(jclass clazz, jfieldID fieldID, + jshort value) { + functions->SetStaticShortField(this,clazz,fieldID,value); + } + void SetStaticIntField(jclass clazz, jfieldID fieldID, + jint value) { + functions->SetStaticIntField(this,clazz,fieldID,value); + } + void SetStaticLongField(jclass clazz, jfieldID fieldID, + jlong value) { + functions->SetStaticLongField(this,clazz,fieldID,value); + } + void SetStaticFloatField(jclass clazz, jfieldID fieldID, + jfloat value) { + functions->SetStaticFloatField(this,clazz,fieldID,value); + } + void SetStaticDoubleField(jclass clazz, jfieldID fieldID, + jdouble value) { + functions->SetStaticDoubleField(this,clazz,fieldID,value); + } + + jstring NewString(const jchar *unicode, jsize len) { + return functions->NewString(this,unicode,len); + } + jsize GetStringLength(jstring str) { + return functions->GetStringLength(this,str); + } + const jchar *GetStringChars(jstring str, jboolean *isCopy) { + return functions->GetStringChars(this,str,isCopy); + } + void ReleaseStringChars(jstring str, const jchar *chars) { + functions->ReleaseStringChars(this,str,chars); + } + + jstring NewStringUTF(const char *utf) { + return functions->NewStringUTF(this,utf); + } + jsize GetStringUTFLength(jstring str) { + return functions->GetStringUTFLength(this,str); + } + const char* GetStringUTFChars(jstring str, jboolean *isCopy) { + return functions->GetStringUTFChars(this,str,isCopy); + } + void ReleaseStringUTFChars(jstring str, const char* chars) { + functions->ReleaseStringUTFChars(this,str,chars); + } + + jsize GetArrayLength(jarray array) { + return functions->GetArrayLength(this,array); + } + + jobjectArray NewObjectArray(jsize len, jclass clazz, + jobject init) { + return functions->NewObjectArray(this,len,clazz,init); + } + jobject GetObjectArrayElement(jobjectArray array, jsize index) { + return functions->GetObjectArrayElement(this,array,index); + } + void SetObjectArrayElement(jobjectArray array, jsize index, + jobject val) { + functions->SetObjectArrayElement(this,array,index,val); + } + + jbooleanArray NewBooleanArray(jsize len) { + return functions->NewBooleanArray(this,len); + } + jbyteArray NewByteArray(jsize len) { + return functions->NewByteArray(this,len); + } + jcharArray NewCharArray(jsize len) { + return functions->NewCharArray(this,len); + } + jshortArray NewShortArray(jsize len) { + return functions->NewShortArray(this,len); + } + jintArray NewIntArray(jsize len) { + return functions->NewIntArray(this,len); + } + jlongArray NewLongArray(jsize len) { + return functions->NewLongArray(this,len); + } + jfloatArray NewFloatArray(jsize len) { + return functions->NewFloatArray(this,len); + } + jdoubleArray NewDoubleArray(jsize len) { + return functions->NewDoubleArray(this,len); + } + + jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) { + return functions->GetBooleanArrayElements(this,array,isCopy); + } + jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) { + return functions->GetByteArrayElements(this,array,isCopy); + } + jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) { + return functions->GetCharArrayElements(this,array,isCopy); + } + jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) { + return functions->GetShortArrayElements(this,array,isCopy); + } + jint * GetIntArrayElements(jintArray array, jboolean *isCopy) { + return functions->GetIntArrayElements(this,array,isCopy); + } + jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) { + return functions->GetLongArrayElements(this,array,isCopy); + } + jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) { + return functions->GetFloatArrayElements(this,array,isCopy); + } + jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) { + return functions->GetDoubleArrayElements(this,array,isCopy); + } + + void ReleaseBooleanArrayElements(jbooleanArray array, + jboolean *elems, + jint mode) { + functions->ReleaseBooleanArrayElements(this,array,elems,mode); + } + void ReleaseByteArrayElements(jbyteArray array, + jbyte *elems, + jint mode) { + functions->ReleaseByteArrayElements(this,array,elems,mode); + } + void ReleaseCharArrayElements(jcharArray array, + jchar *elems, + jint mode) { + functions->ReleaseCharArrayElements(this,array,elems,mode); + } + void ReleaseShortArrayElements(jshortArray array, + jshort *elems, + jint mode) { + functions->ReleaseShortArrayElements(this,array,elems,mode); + } + void ReleaseIntArrayElements(jintArray array, + jint *elems, + jint mode) { + functions->ReleaseIntArrayElements(this,array,elems,mode); + } + void ReleaseLongArrayElements(jlongArray array, + jlong *elems, + jint mode) { + functions->ReleaseLongArrayElements(this,array,elems,mode); + } + void ReleaseFloatArrayElements(jfloatArray array, + jfloat *elems, + jint mode) { + functions->ReleaseFloatArrayElements(this,array,elems,mode); + } + void ReleaseDoubleArrayElements(jdoubleArray array, + jdouble *elems, + jint mode) { + functions->ReleaseDoubleArrayElements(this,array,elems,mode); + } + + void GetBooleanArrayRegion(jbooleanArray array, + jsize start, jsize len, jboolean *buf) { + functions->GetBooleanArrayRegion(this,array,start,len,buf); + } + void GetByteArrayRegion(jbyteArray array, + jsize start, jsize len, jbyte *buf) { + functions->GetByteArrayRegion(this,array,start,len,buf); + } + void GetCharArrayRegion(jcharArray array, + jsize start, jsize len, jchar *buf) { + functions->GetCharArrayRegion(this,array,start,len,buf); + } + void GetShortArrayRegion(jshortArray array, + jsize start, jsize len, jshort *buf) { + functions->GetShortArrayRegion(this,array,start,len,buf); + } + void GetIntArrayRegion(jintArray array, + jsize start, jsize len, jint *buf) { + functions->GetIntArrayRegion(this,array,start,len,buf); + } + void GetLongArrayRegion(jlongArray array, + jsize start, jsize len, jlong *buf) { + functions->GetLongArrayRegion(this,array,start,len,buf); + } + void GetFloatArrayRegion(jfloatArray array, + jsize start, jsize len, jfloat *buf) { + functions->GetFloatArrayRegion(this,array,start,len,buf); + } + void GetDoubleArrayRegion(jdoubleArray array, + jsize start, jsize len, jdouble *buf) { + functions->GetDoubleArrayRegion(this,array,start,len,buf); + } + + void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, + const jboolean *buf) { + functions->SetBooleanArrayRegion(this,array,start,len,buf); + } + void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, + const jbyte *buf) { + functions->SetByteArrayRegion(this,array,start,len,buf); + } + void SetCharArrayRegion(jcharArray array, jsize start, jsize len, + const jchar *buf) { + functions->SetCharArrayRegion(this,array,start,len,buf); + } + void SetShortArrayRegion(jshortArray array, jsize start, jsize len, + const jshort *buf) { + functions->SetShortArrayRegion(this,array,start,len,buf); + } + void SetIntArrayRegion(jintArray array, jsize start, jsize len, + const jint *buf) { + functions->SetIntArrayRegion(this,array,start,len,buf); + } + void SetLongArrayRegion(jlongArray array, jsize start, jsize len, + const jlong *buf) { + functions->SetLongArrayRegion(this,array,start,len,buf); + } + void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, + const jfloat *buf) { + functions->SetFloatArrayRegion(this,array,start,len,buf); + } + void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, + const jdouble *buf) { + functions->SetDoubleArrayRegion(this,array,start,len,buf); + } + + jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, + jint nMethods) { + return functions->RegisterNatives(this,clazz,methods,nMethods); + } + jint UnregisterNatives(jclass clazz) { + return functions->UnregisterNatives(this,clazz); + } + + jint MonitorEnter(jobject obj) { + return functions->MonitorEnter(this,obj); + } + jint MonitorExit(jobject obj) { + return functions->MonitorExit(this,obj); + } + + jint GetJavaVM(JavaVM **vm) { + return functions->GetJavaVM(this,vm); + } + + void GetStringRegion(jstring str, jsize start, jsize len, jchar *buf) { + functions->GetStringRegion(this,str,start,len,buf); + } + void GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) { + functions->GetStringUTFRegion(this,str,start,len,buf); + } + + void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) { + return functions->GetPrimitiveArrayCritical(this,array,isCopy); + } + void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) { + functions->ReleasePrimitiveArrayCritical(this,array,carray,mode); + } + + const jchar * GetStringCritical(jstring string, jboolean *isCopy) { + return functions->GetStringCritical(this,string,isCopy); + } + void ReleaseStringCritical(jstring string, const jchar *cstring) { + functions->ReleaseStringCritical(this,string,cstring); + } + + jweak NewWeakGlobalRef(jobject obj) { + return functions->NewWeakGlobalRef(this,obj); + } + void DeleteWeakGlobalRef(jweak ref) { + functions->DeleteWeakGlobalRef(this,ref); + } + + jboolean ExceptionCheck() { + return functions->ExceptionCheck(this); + } + + jobject NewDirectByteBuffer(void* address, jlong capacity) { + return functions->NewDirectByteBuffer(this, address, capacity); + } + void* GetDirectBufferAddress(jobject buf) { + return functions->GetDirectBufferAddress(this, buf); + } + jlong GetDirectBufferCapacity(jobject buf) { + return functions->GetDirectBufferCapacity(this, buf); + } + jobjectRefType GetObjectRefType(jobject obj) { + return functions->GetObjectRefType(this, obj); + } + +#endif /* __cplusplus */ +}; + +typedef struct JavaVMOption { + char *optionString; + void *extraInfo; +} JavaVMOption; + +typedef struct JavaVMInitArgs { + jint version; + + jint nOptions; + JavaVMOption *options; + jboolean ignoreUnrecognized; +} JavaVMInitArgs; + +typedef struct JavaVMAttachArgs { + jint version; + + char *name; + jobject group; +} JavaVMAttachArgs; + +/* These will be VM-specific. */ + +#define JDK1_2 +#define JDK1_4 + +/* End VM-specific. */ + +struct JNIInvokeInterface_ { + void *reserved0; + void *reserved1; + void *reserved2; + + jint (JNICALL *DestroyJavaVM)(JavaVM *vm); + + jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args); + + jint (JNICALL *DetachCurrentThread)(JavaVM *vm); + + jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version); + + jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args); +}; + +struct JavaVM_ { + const struct JNIInvokeInterface_ *functions; +#ifdef __cplusplus + + jint DestroyJavaVM() { + return functions->DestroyJavaVM(this); + } + jint AttachCurrentThread(void **penv, void *args) { + return functions->AttachCurrentThread(this, penv, args); + } + jint DetachCurrentThread() { + return functions->DetachCurrentThread(this); + } + + jint GetEnv(void **penv, jint version) { + return functions->GetEnv(this, penv, version); + } + jint AttachCurrentThreadAsDaemon(void **penv, void *args) { + return functions->AttachCurrentThreadAsDaemon(this, penv, args); + } +#endif +}; + +#ifdef _JNI_IMPLEMENTATION_ +#define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT +#else +#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT +#endif +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetDefaultJavaVMInitArgs(void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args); + +_JNI_IMPORT_OR_EXPORT_ jint JNICALL +JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *); + +/* Defined by native libraries. */ +JNIEXPORT jint JNICALL +JNI_OnLoad(JavaVM *vm, void *reserved); + +JNIEXPORT void JNICALL +JNI_OnUnload(JavaVM *vm, void *reserved); + +#define JNI_VERSION_1_1 0x00010001 +#define JNI_VERSION_1_2 0x00010002 +#define JNI_VERSION_1_4 0x00010004 +#define JNI_VERSION_1_6 0x00010006 + +#ifdef __cplusplus +} /* extern "C" */ +#endif /* __cplusplus */ + +#endif /* !_JAVASOFT_JNI_H_ */ + + + diff --git a/org.simantics.matlablink.win32.x86_64/src/jni_md.h b/org.simantics.matlablink.win32.x86_64/src/jni_md.h new file mode 100644 index 0000000..9f0cfa4 --- /dev/null +++ b/org.simantics.matlablink.win32.x86_64/src/jni_md.h @@ -0,0 +1,19 @@ +/* + * @(#)jni_md.h 1.15 05/11/17 + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + */ + +#ifndef _JAVASOFT_JNI_MD_H_ +#define _JAVASOFT_JNI_MD_H_ + +#define JNIEXPORT __declspec(dllexport) +#define JNIIMPORT __declspec(dllimport) +#define JNICALL __stdcall + +typedef long jint; +typedef __int64 jlong; +typedef signed char jbyte; + +#endif /* !_JAVASOFT_JNI_MD_H_ */ diff --git a/org.simantics.matlablink.win32.x86_64/src/jnimatlab.vcxproj b/org.simantics.matlablink.win32.x86_64/src/jnimatlab.vcxproj new file mode 100644 index 0000000..8aca77e --- /dev/null +++ b/org.simantics.matlablink.win32.x86_64/src/jnimatlab.vcxproj @@ -0,0 +1,130 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {1C933BCE-5239-49A7-A553-6F9993223A2F} + jnimatlab + + + + DynamicLibrary + true + MultiByte + + + DynamicLibrary + true + MultiByte + + + DynamicLibrary + false + true + MultiByte + + + DynamicLibrary + false + true + MultiByte + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + .;C:\Program Files (x86)\MATLAB\R2014b\extern\include + + + true + C:\Program Files (x86)\MATLAB\R2014b\extern\lib\win32\microsoft + libeng.lib;libmx.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + Disabled + .;C:\Program Files (x86)\MATLAB\R2014b\extern\include + + + true + C:\Program Files\MATLAB\R2014b\extern\lib\win64\microsoft + libeng.lib;libmx.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + .;C:\Program Files (x86)\MATLAB\R2014b\extern\include + + + true + true + true + C:\Program Files (x86)\MATLAB\R2014b\extern\lib\win32\microsoft + libeng.lib;libmx.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + .;C:\Program Files (x86)\MATLAB\R2014b\extern\include + + + true + true + true + C:\Program Files\MATLAB\R2014b\extern\lib\win64\microsoft + libeng.lib;libmx.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + + + + + \ No newline at end of file diff --git a/org.simantics.matlablink.win32.x86_64/src/jnimatlab.vcxproj.filters b/org.simantics.matlablink.win32.x86_64/src/jnimatlab.vcxproj.filters new file mode 100644 index 0000000..9993981 --- /dev/null +++ b/org.simantics.matlablink.win32.x86_64/src/jnimatlab.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/org.simantics.matlablink.win32.x86_64/src/sclmat.c b/org.simantics.matlablink.win32.x86_64/src/sclmat.c new file mode 100644 index 0000000..f2dab65 --- /dev/null +++ b/org.simantics.matlablink.win32.x86_64/src/sclmat.c @@ -0,0 +1,791 @@ +/////////////////////////////////////////////////////// +// // +// VTT Technical Research Centre of Finland LTD // +// For internal use only. Do not redistribute. // +// // +// Authors: // +// Antton Tapani ext-antton.tapani@vtt.fi // +// // +// Last modified by Antton Tapani 9.2016 // +// // +/////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include "engine.h" +#include + +#pragma warning(disable: 4996) + +#define UTF8FEATURE "feature('DefaultCharacterSet', 'UTF-8')" + +#define BUFSIZE 1000 + +#define MAXJSIZE MAXLONG +#define MAXJINT MAXLONG + +#define tojsize(x) ((jsize)(min((x), MAXJSIZE))) +#define tojint(x) ((jint)(min((x), MAXJINT))) + +jobject getJavaStructArray(JNIEnv *env, mxArray *matlabArray); +jobject getJavaCharacterArray(JNIEnv *env, mxArray *matlabArray); +jobject getJavaDoubleArray(JNIEnv *env, mxArray *matlabArray); +jobject getJavaCellArray(JNIEnv *env, mxArray *matlabArray); +jobject getJavaArray(JNIEnv *env, mxArray *item); + +mxArray *getMatlabArray(JNIEnv *env, jobject item); +mxArray *getMatlabDoubleArray(JNIEnv *env, jobject value); +mxArray *getMatlabCharacterArray(JNIEnv *env, jobject value); +mxArray *getMatlabStructArray(JNIEnv *env, jobject value); +mxArray *getMatlabCellArray(JNIEnv *env, jobject value); + +jint throwException( JNIEnv *env, char *className, char *message ) +{ + jclass exClass = (*env)->FindClass( env, className); + if (exClass == NULL) { + return 0; + } + + return (*env)->ThrowNew( env, exClass, message ); +} + +jint throwIllegalArgumentException( JNIEnv *env, char *message ) { + return throwException( env, "java/lang/IllegalArgumentException", message ); +} + +/** + * Get the dimensions of a Matlab array as a Java integer[]. + * The value pointed to by nelems is set to the total number of elements int + * the array. + */ +jintArray getMatlabArrayDims(JNIEnv *env, mxArray *matlabArray) { + int i; + + size_t ndims = mxGetNumberOfDimensions(matlabArray); + const size_t *dims = mxGetDimensions(matlabArray); + + jintArray jdims = (*env)->NewIntArray(env, tojsize(ndims)); + + for (i = 0; i < ndims; i++) { + jsize dim = tojsize(dims[i]); + (*env)->SetIntArrayRegion(env, jdims, i, 1, &dim); + } + + return jdims; +} + +/** + * Get the contents of a Matlab double array as (Java) double[]. + */ +jobject getJavaDoubleArray(JNIEnv *env, mxArray *matlabArray) { + jclass doubleArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/DoubleArray"); + jmethodID constructor = (*env)->GetMethodID(env, doubleArrayClass, "", "([I[D)V"); + + jsize nelems = tojsize(mxGetNumberOfElements(matlabArray)); + jdoubleArray values = (*env)->NewDoubleArray(env, nelems); + double *contents = mxGetPr(matlabArray); + (*env)->SetDoubleArrayRegion(env, values, 0, nelems, contents); + + { + jintArray jdims = getMatlabArrayDims(env, matlabArray); + jobject result = (*env)->NewObject(env, doubleArrayClass, constructor, jdims, values); + return result; + } +} + +/** + * Get the contents of a Matlab character array as java.lang.String. + */ +jobject getJavaCharacterArray(JNIEnv *env, mxArray *matlabArray) { + jclass characterArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/CharacterArray"); + jmethodID constructor = (*env)->GetMethodID(env, characterArrayClass, "", "([I[C)V"); + + { + size_t len = mxGetNumberOfElements(matlabArray); + mxChar *buf = mxGetChars(matlabArray); + jintArray jdims = getMatlabArrayDims(env, matlabArray); + jcharArray bytes = (*env)->NewCharArray(env, tojsize(len)); + (*env)->SetCharArrayRegion(env, bytes, 0, tojsize(len), buf); + { + jobject result = (*env)->NewObject(env, characterArrayClass, constructor, jdims, bytes); + return result; + } + } +} + +/** + * Get the contents of a Matlab struct array as java.util.Map[]. + */ +jobject getJavaStructArray(JNIEnv *env, mxArray *matlabArray) { + jclass structArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/StructArray"); + jmethodID constructor = (*env)->GetMethodID(env, structArrayClass, "", "([ILjava/util/Collection;)V"); + jmethodID setFieldMethod = (*env)->GetMethodID(env, structArrayClass, "setField", "(ILjava/lang/String;Lorg/simantics/matlablink/MatlabArray;)V"); + + jclass arrayListClass = (*env)->FindClass(env, "java/util/ArrayList"); + jmethodID arrayListConstructor = (*env)->GetMethodID(env, arrayListClass, "", "()V"); + jmethodID addMethod = (*env)->GetMethodID(env, arrayListClass, "add", "(Ljava/lang/Object;)Z"); + jmethodID getMethod = (*env)->GetMethodID(env, arrayListClass, "get", "(I)Ljava/lang/Object;"); + + size_t nelems = mxGetNumberOfElements(matlabArray); + jintArray jdims = getMatlabArrayDims(env, matlabArray); + size_t len = mxGetNumberOfElements(matlabArray); + int nFields = mxGetNumberOfFields(matlabArray); + jsize jlen = tojsize(len); + + jobject fields = (*env)->NewObject(env, arrayListClass, arrayListConstructor); + + int j; + + for (j = 0; j < nFields; j++) { + jstring fieldName = (*env)->NewStringUTF(env, mxGetFieldNameByNumber(matlabArray, j)); + (*env)->CallVoidMethod(env, fields, addMethod, fieldName); + } + + { + jobject result = (*env)->NewObject(env, structArrayClass, constructor, jdims, fields); + + for (j = 0; j < nFields; j++) { + jstring fieldName = (jstring)(*env)->CallObjectMethod(env, fields, getMethod, j); + jint i; + for (i = 0; i < jlen; i++) { + jobject value = getJavaArray(env, mxGetFieldByNumber(matlabArray, i, j)); + (*env)->CallVoidMethod(env, result, setFieldMethod, i, fieldName, value); + } + } + + return result; + } +} + +/** + * Get the contents of a Matlab cell array as java.lang.Object[]. + */ +jobject getJavaCellArray(JNIEnv *env, mxArray *matlabArray) { + size_t i; + jclass cellArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/CellArray"); + jmethodID constructor = (*env)->GetMethodID(env, cellArrayClass, "", "([I)V"); + jmethodID setCellItemMethod = (*env)->GetMethodID(env, cellArrayClass, "setCellItem", "(ILorg/simantics/matlablink/MatlabArray;)V"); + + jintArray jdims = getMatlabArrayDims(env, matlabArray); + jobject result = (*env)->NewObject(env, cellArrayClass, constructor, jdims); + + size_t len = mxGetNumberOfElements(matlabArray); + for (i = 0; i < len; i++) { + mxArray *item = mxGetCell(matlabArray, i); + if (item != NULL) + (*env)->CallVoidMethod(env, result, setCellItemMethod, (jint)i, getJavaArray(env, item)); + } + + return result; +} + +/** + * Get the value of a Matlab array as a type-dependent Java object. + * + * The currently supported Matlab data types are: + * - character + * - double + * - struct + * - cell + */ +jobject getJavaArray(JNIEnv *env, mxArray *item) { + switch (mxGetClassID(item)) { + case mxCHAR_CLASS: + return getJavaCharacterArray(env, item); + break; + case mxCELL_CLASS: + return getJavaCellArray(env, item); + break; + case mxSTRUCT_CLASS: + return getJavaStructArray(env, item); + break; + case mxDOUBLE_CLASS: + return getJavaDoubleArray(env, item); + break; + default: + return NULL; + break; + } +} + +JNIEXPORT jlong JNICALL Java_org_simantics_matlablink_Engine_openMatlabEngineImpl(JNIEnv *env, jobject thisObj, jstring workingDirectory) { + jsize len = (*env)->GetStringUTFLength(env, workingDirectory); + const char *bytes = (*env)->GetStringUTFChars(env, workingDirectory, NULL); + char *buf = (char*)malloc(len + 6); + + // Open Matlab engine + Engine *engine = engOpen(NULL); + jlong result = (jlong)engine; + + // Make Matlab use UTF-8 by default + engEvalString(engine, UTF8FEATURE); + + // Switch current directory + sprintf(buf, "cd('%s')", bytes); + (*env)->ReleaseStringUTFChars(env, workingDirectory, bytes); + engEvalString(engine, buf); + + // Return the engine pointer as a Java long + return result; +} + +JNIEXPORT void JNICALL Java_org_simantics_matlablink_Engine_closeMatlabEngineImpl(JNIEnv *env, jobject thisObj, jlong engineID) { + Engine *engine = (Engine *)engineID; + engClose(engine); +} + +mxArray *getMatlabVariable(JNIEnv *env, Engine *engine, jstring variableName) { + const char *name = (*env)->GetStringUTFChars(env, variableName, NULL); + mxArray *result = engGetVariable(engine, name); + (*env)->ReleaseStringUTFChars(env, variableName, name); + return result; +} + +int putMatlabVariable(JNIEnv *env, Engine *engine, jstring variableName, mxArray *value) { + const char *name = (*env)->GetStringUTFChars(env, variableName, NULL); + int status = engPutVariable(engine, name, value); + (*env)->ReleaseStringUTFChars(env, variableName, name); + return status; +} + +mxArray *getMatlabDoubleArray(JNIEnv *env, jobject javaObject) { + jclass doubleArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/DoubleArray"); + jmethodID getDoubleValueMethod = (*env)->GetMethodID(env, doubleArrayClass, "getDoubleValue", "()[D"); + jmethodID dimsMethod = (*env)->GetMethodID(env, doubleArrayClass, "dims", "()[I"); + + jdoubleArray value = (*env)->CallObjectMethod(env, javaObject, getDoubleValueMethod); + jintArray jdims = (*env)->CallObjectMethod(env, javaObject, dimsMethod); + + // Get vector dimentions + jsize ndims = (*env)->GetArrayLength(env, jdims); + jsize *jdimArray = (*env)->GetIntArrayElements(env, jdims, NULL); + size_t *dims = (size_t*)malloc(ndims * sizeof(size_t)); + + jint i; + + for (i = 0; i < ndims; i++) { + dims[i] = jdimArray[i]; + } + + (*env)->ReleaseIntArrayElements(env, jdims, jdimArray, JNI_ABORT); + + { + mxArray *result = mxCreateNumericArray(ndims, dims, mxDOUBLE_CLASS, mxREAL); + jsize len = (*env)->GetArrayLength(env, value); + double *data = mxGetPr(result); + double *jdata = (*env)->GetDoubleArrayElements(env, value, NULL); + + free(dims); + + // Copy data from Java array + memcpy(data, jdata, len * sizeof(double)); + + (*env)->ReleaseDoubleArrayElements(env, value, jdata, JNI_ABORT); + + return result; + } +} + +mxArray *getMatlabCharacterArray(JNIEnv *env, jobject javaArray) { + jclass characterArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/CharacterArray"); + jmethodID getCharactersMethod = (*env)->GetMethodID(env, characterArrayClass, "getCharacters", "()[C"); + jmethodID dimsMethod = (*env)->GetMethodID(env, characterArrayClass, "dims", "()[I"); + + jcharArray value = (jcharArray)(*env)->CallObjectMethod(env, javaArray, getCharactersMethod); + jintArray jdims = (*env)->CallObjectMethod(env, javaArray, dimsMethod); + + // Get vector dimentions + jsize ndims = (*env)->GetArrayLength(env, jdims); + jsize *jdimArray = (*env)->GetIntArrayElements(env, jdims, NULL); + size_t *dims = (size_t*)malloc(ndims * sizeof(size_t)); + + jint i; + + for (i = 0; i < ndims; i++) { + dims[i] = jdimArray[i]; + } + + { + mxArray *charArray = mxCreateCharArray(ndims, dims); + + jsize len = (*env)->GetArrayLength(env, value); + jchar *bytes = (*env)->GetCharArrayElements(env, value, NULL); + mxChar *bytesOut = mxGetChars(charArray); + + free(dims); + (*env)->ReleaseIntArrayElements(env, jdims, jdimArray, JNI_ABORT); + + memcpy(bytesOut, bytes, len * sizeof(jchar)); + + (*env)->ReleaseCharArrayElements(env, value, bytes, JNI_ABORT); + + return charArray; + } +} + +mxArray *getMatlabStructArray(JNIEnv *env, jobject value) { + jclass structArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/StructArray"); + jmethodID getFieldMethod = (*env)->GetMethodID(env, structArrayClass, "getField", "(ILjava/lang/String;)Lorg/simantics/matlablink/MatlabArray;"); + jmethodID getFieldsMethod = (*env)->GetMethodID(env, structArrayClass, "getFields", "()[Ljava/lang/String;"); + jmethodID dimsMethod = (*env)->GetMethodID(env, structArrayClass, "dims", "()[I"); + + jobjectArray fields = (*env)->CallObjectMethod(env, value, getFieldsMethod); + + jint i, nfields = (*env)->GetArrayLength(env, fields); + char **fieldNames = (char**)malloc(nfields * sizeof(char*)); + + for (i = 0; i < nfields; i++) { + jstring field = (jstring)(*env)->GetObjectArrayElement(env, fields, i); + const char *chars = (*env)->GetStringUTFChars(env, field, NULL); + fieldNames[i] = strdup(chars); + (*env)->ReleaseStringUTFChars(env, field, chars); + } + + { + // Get vector dimentions + jintArray jdims = (*env)->CallObjectMethod(env, value, dimsMethod); + jsize ndims = (*env)->GetArrayLength(env, jdims); + jsize *jdimArray = (*env)->GetIntArrayElements(env, jdims, NULL); + size_t *dims = (size_t*)malloc(ndims * sizeof(size_t)); + mxArray *result; + jsize len = ndims > 0 ? 1 : 0; + + for (i = 0; i < ndims; i++) { + dims[i] = jdimArray[i]; + len = len * jdimArray[i]; + } + + result = mxCreateStructArray(ndims, dims, nfields, fieldNames); + + free(dims); + + for (i = 0; i < nfields; i++) { + jstring field = (jstring)(*env)->GetObjectArrayElement(env, fields, i); + int j; + + for (j = 0; j < len; j++) { + jobject item = (*env)->CallObjectMethod(env, value, getFieldMethod, (jint)j, field); + mxSetFieldByNumber(result, j, i, getMatlabArray(env, item)); + } + } + + for (i = 0; i < nfields; i++) + if (fieldNames[i] != NULL) free(fieldNames[i]); + + free(fieldNames); + + return result; + } +} + +mxArray *getMatlabCellArray(JNIEnv *env, jobject value) { + jclass cellArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/CellArray"); + jmethodID getCellValueMethod = (*env)->GetMethodID(env, cellArrayClass, "getCellValue", "()[Lorg/simantics/matlablink/MatlabArray;"); + jmethodID dimsMethod = (*env)->GetMethodID(env, cellArrayClass, "dims", "()[I"); + + jobjectArray values = (*env)->CallObjectMethod(env, value, getCellValueMethod); + jintArray jdims = (*env)->CallObjectMethod(env, value, dimsMethod); + + // Get vector dimentions + jsize len = (*env)->GetArrayLength(env, values); + jsize ndims = (*env)->GetArrayLength(env, jdims); + jsize *jdimArray = (*env)->GetIntArrayElements(env, jdims, NULL); + size_t *dims = (size_t*)malloc(ndims * sizeof(size_t)); + + jint i; + + for (i = 0; i < ndims; i++) { + dims[i] = jdimArray[i]; + } + + { + // Create temporary Matlab array + mxArray *matlabValue = mxCreateCellArray(ndims, dims); + + // Copy data from Java array + for (i = 0; i < len; i++) { + jobject item = (*env)->GetObjectArrayElement(env, values, i); + mxArray *matlabItem = getMatlabArray(env, item); + if (matlabItem != NULL) { + mxSetCell(matlabValue, i, matlabItem); + } + } + + return matlabValue; + } +} + +mxArray *getMatlabArray(JNIEnv *env, jobject item) { + jclass doubleArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/DoubleArray"); + jclass characterArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/CharacterArray"); + jclass cellArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/CellArray"); + jclass structArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/StructArray"); + + mxArray *matlabItem = NULL; + if ((*env)->IsInstanceOf(env, item, doubleArrayClass)) { + matlabItem = getMatlabDoubleArray(env, item); + } + else if ((*env)->IsInstanceOf(env, item, characterArrayClass)) { + matlabItem = getMatlabCharacterArray(env, item); + } + else if ((*env)->IsInstanceOf(env, item, cellArrayClass)) { + matlabItem = getMatlabCellArray(env, item); + } + else if ((*env)->IsInstanceOf(env, item, structArrayClass)) { + matlabItem = getMatlabStructArray(env, item); + } + + return matlabItem; +} + +// Generic arrays +JNIEXPORT jobject JNICALL Java_org_simantics_matlablink_Engine_getMatlabArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring varName) { + Engine *engine = (Engine *)engineID; + + if (varName == NULL) { + throwIllegalArgumentException(env, "Null variable name given"); + } + + { + mxArray *array = getMatlabVariable(env, engine, varName); + + if (array == NULL) { + throwException(env, "java/lang/RuntimeException", "Variable not found"); + return NULL; + } + + { + jobject result = getJavaArray(env, array); + + mxDestroyArray(array); + + if (result == NULL) { + throwException(env, "java/lang/RuntimeException", "Matlab variable type not supported"); + return NULL; + } + + return result; + } + } +} + +JNIEXPORT jint JNICALL Java_org_simantics_matlablink_Engine_setMatlabArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring variableName, jobject value) { + if (variableName == NULL) { + throwIllegalArgumentException(env, "Null variable name given"); + return 0; + } + + if (value == NULL) { + throwIllegalArgumentException(env, "Null variable value given"); + return 0; + } + + { + Engine *engine = (Engine *)engineID; + + // Get value as mxArray + mxArray *matlabValue = getMatlabArray(env, value); + + if (matlabValue == NULL) { + throwException(env, "java/lang/RuntimeException", "Input not a suitable value for a Matlab array"); + return 0; + } + + { + // Set variable value + int status = putMatlabVariable(env, engine, variableName, matlabValue); + + // Destroy array object + mxDestroyArray(matlabValue); + + return status; + } + } +} + +// Double arrays +JNIEXPORT jobject JNICALL Java_org_simantics_matlablink_Engine_getMatlabDoubleArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring varName) { + Engine *engine = (Engine *)engineID; + + if (varName == NULL) { + throwIllegalArgumentException(env, "Null variable name given"); + } + + { + mxArray *array = getMatlabVariable(env, engine, varName); + + if (array == NULL) { + throwException(env, "java/lang/RuntimeException", "Variable not found"); + return NULL; + } + + if (!mxIsDouble(array)) { + throwException(env, "java/lang/RuntimeException", "Variable not a double array"); + return NULL; + } + + { + jdoubleArray result = getJavaDoubleArray(env, array); + mxDestroyArray(array); + return result; + } + } +} + +JNIEXPORT jint JNICALL Java_org_simantics_matlablink_Engine_setMatlabDoubleArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring variableName, jobject value) { + if (variableName == NULL) { + throwIllegalArgumentException(env, "Null variable name given"); + return 0; + } + + if (value == NULL) { + throwIllegalArgumentException(env, "Null variable value given"); + return 0; + } + + { + Engine *engine = (Engine *)engineID; + + // Get value as mxArray + mxArray *matlabValue = getMatlabDoubleArray(env, value); + + // Set variable value + int status = putMatlabVariable(env, engine, variableName, matlabValue); + + // Destroy array object + mxDestroyArray(matlabValue); + + return status; + } +} + +// Cell arrays +JNIEXPORT jobject JNICALL Java_org_simantics_matlablink_Engine_getMatlabCellArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring varName) { + Engine *engine = (Engine *)engineID; + + if (varName == NULL) { + throwIllegalArgumentException(env, "Null variable name given"); + return NULL; + } + + { + // Get variable value from Matlab + mxArray *array = getMatlabVariable(env, engine, varName); + + if (array == NULL) { + throwException(env, "java/lang/RuntimeException", "Variable not found"); + return NULL; + } + + if (!mxIsCell(array)) { + throwException(env, "java/lang/RuntimeException", "Variable not a cell array"); + return NULL; + } + + { + jobject result = getJavaCellArray(env, array); + mxDestroyArray(array); + + if (result == NULL) { + throwException(env, "java/lang/RuntimeException", "Matlab variable type not supported"); + return NULL; + } + + return result; + } + } +} + +JNIEXPORT jint JNICALL Java_org_simantics_matlablink_Engine_setMatlabCellArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring variableName, jobject value) { + if (variableName == NULL) { + throwIllegalArgumentException(env, "Null variable name given"); + return 0; + } + + if (value == NULL) { + throwIllegalArgumentException(env, "Null variable value given"); + return 0; + } + + { + Engine *engine = (Engine *)engineID; + + // Get value as mxArray + mxArray *matlabValue = getMatlabCellArray(env, value); + + // Set variable value + int status = putMatlabVariable(env, engine, variableName, matlabValue); + + // Destroy array object + mxDestroyArray(matlabValue); + + return status; + } +} + +// Character arrays +JNIEXPORT jobject JNICALL Java_org_simantics_matlablink_Engine_getMatlabCharacterArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring varName) { + Engine *engine = (Engine *)engineID; + + if (varName == NULL) { + throwIllegalArgumentException(env, "Null variable name given"); + return NULL; + } + + { + // Get variable value from Matlab + mxArray *array = getMatlabVariable(env, engine, varName); + + if (array == NULL) { + throwException(env, "java/lang/RuntimeException", "Variable not found"); + return NULL; + } + + if (!mxIsChar(array)) { + throwException(env, "java/lang/RuntimeException", "Variable not a character array"); + return NULL; + } + + { + jobject result = getJavaCharacterArray(env, array); + mxDestroyArray(array); + + if (result == NULL) { + throwException(env, "java/lang/RuntimeException", "Matlab variable type not supported"); + return NULL; + } + + return result; + } + } +} + +JNIEXPORT jint JNICALL Java_org_simantics_matlablink_Engine_setMatlabCharacterArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring variableName, jobject value) { + if (variableName == NULL) { + throwIllegalArgumentException(env, "Null variable name given"); + return 0; + } + + if (value == NULL) { + throwIllegalArgumentException(env, "Null variable value given"); + return 0; + } + + { + Engine *engine = (Engine *)engineID; + + // Get value as mxArray + mxArray *matlabValue = getMatlabCharacterArray(env, value); + + // Set variable value + int status = putMatlabVariable(env, engine, variableName, matlabValue); + + // Destroy array object + mxDestroyArray(matlabValue); + + return status; + } +} + +// Struct arrays +JNIEXPORT jobject JNICALL Java_org_simantics_matlablink_Engine_getMatlabStructArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring varName) { + Engine *engine = (Engine *)engineID; + + if (varName == NULL) { + throwIllegalArgumentException(env, "Null variable name given"); + return NULL; + } + + { + // Get variable value from Matlab + mxArray *array = getMatlabVariable(env, engine, varName); + + if (array == NULL) { + throwException(env, "java/lang/RuntimeException", "Variable not found"); + return NULL; + } + + if (!mxIsStruct(array)) { + throwException(env, "java/lang/RuntimeException", "Variable not a struct array"); + return NULL; + } + + { + jobject result = getJavaStructArray(env, array); + mxDestroyArray(array); + + if (result == NULL) { + throwException(env, "java/lang/RuntimeException", "Matlab variable type not supported"); + return NULL; + } + + return result; + } + } +} + +JNIEXPORT jint JNICALL Java_org_simantics_matlablink_Engine_setMatlabStructArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring variableName, jobject value) { + if (variableName == NULL) { + throwIllegalArgumentException(env, "Null variable name given"); + return 0; + } + + if (value == NULL) { + throwIllegalArgumentException(env, "Null variable value given"); + return 0; + } + + { + Engine *engine = (Engine *)engineID; + + // Get value as mxArray + mxArray *matlabValue = getMatlabStructArray(env, value); + + // Set variable value + int status = putMatlabVariable(env, engine, variableName, matlabValue); + + // Destroy array object + mxDestroyArray(matlabValue); + + return status; + } +} + +// Expression evaluation +JNIEXPORT jint JNICALL Java_org_simantics_matlablink_Engine_evaluateMatlabExpressionImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring expression) { + Engine *engine = (Engine *)engineID; + const char *expr = (*env)->GetStringUTFChars(env, expression, NULL); + + int status = engEvalString(engine, expr); + + (*env)->ReleaseStringUTFChars(env, expression, expr); + + return status; +} + +//extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + // attach to process + break; + + case DLL_PROCESS_DETACH: + // detach from process + break; + + case DLL_THREAD_ATTACH: + // attach to thread + break; + + case DLL_THREAD_DETACH: + // detach from thread + break; + } + return TRUE; // succesful +} diff --git a/org.simantics.matlablink.win32.x86_64/src/sclmat.h b/org.simantics.matlablink.win32.x86_64/src/sclmat.h new file mode 100644 index 0000000..e432609 --- /dev/null +++ b/org.simantics.matlablink.win32.x86_64/src/sclmat.h @@ -0,0 +1,27 @@ +#ifndef __SCLMAT_H__ +#define __SCLMAT_H__ + +#include + +/* To use this exported function of dll, include this header + * in your project. + */ + +#ifdef BUILD_DLL + #define DLL_EXPORT __declspec(dllexport) +#else + #define DLL_EXPORT __declspec(dllimport) +#endif + + +#ifdef __cplusplus +extern "C" +{ +#endif + +__declspec (dllexport) void __stdcall start(char*, double*, int, int); +#ifdef __cplusplus +} +#endif + +#endif // __SCLMAT_H__ diff --git a/org.simantics.matlablink/.classpath b/org.simantics.matlablink/.classpath new file mode 100644 index 0000000..069739a --- /dev/null +++ b/org.simantics.matlablink/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.simantics.matlablink/.gitignore b/org.simantics.matlablink/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/org.simantics.matlablink/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/org.simantics.matlablink/.project b/org.simantics.matlablink/.project new file mode 100644 index 0000000..f8aba66 --- /dev/null +++ b/org.simantics.matlablink/.project @@ -0,0 +1,28 @@ + + + org.simantics.matlablink + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.simantics.matlablink/.settings/org.eclipse.core.resources.prefs b/org.simantics.matlablink/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..e6babf3 --- /dev/null +++ b/org.simantics.matlablink/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding//test/org/simantics/matlablink/test/TestMatlabEngine.java=UTF-8 diff --git a/org.simantics.matlablink/.settings/org.eclipse.jdt.core.prefs b/org.simantics.matlablink/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..295926d --- /dev/null +++ b/org.simantics.matlablink/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/org.simantics.matlablink/META-INF/MANIFEST.MF b/org.simantics.matlablink/META-INF/MANIFEST.MF new file mode 100644 index 0000000..d013e1c --- /dev/null +++ b/org.simantics.matlablink/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Matlablink +Bundle-SymbolicName: org.simantics.matlablink +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Require-Bundle: org.junit, + org.eclipse.osgi, + org.simantics.scl.runtime, + gnu.trove3;bundle-version="3.0.3" +Export-Package: org.simantics.matlablink +Bundle-Activator: org.simantics.matlablink.Activator +Bundle-ActivationPolicy: lazy diff --git a/org.simantics.matlablink/build.properties b/org.simantics.matlablink/build.properties new file mode 100644 index 0000000..840ba6a --- /dev/null +++ b/org.simantics.matlablink/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + scl/ +src.includes = scl/ \ No newline at end of file diff --git a/org.simantics.matlablink/scl/Simantics/Matlab.scl b/org.simantics.matlablink/scl/Simantics/Matlab.scl new file mode 100644 index 0000000..811e0aa --- /dev/null +++ b/org.simantics.matlablink/scl/Simantics/Matlab.scl @@ -0,0 +1,97 @@ +import "Map" as Map +import "Vector" +import "File" + +effect Matlab + "Simantics/Matlab/Matlab" + "org.simantics.matlablink.Engine" + +importJava "org.simantics.matlablink.MatlabArray" + data MatlabArray +importJava "org.simantics.matlablink.DoubleArray" + data DoubleArray +importJava "org.simantics.matlablink.CharacterArray" + data CharacterArray +importJava "org.simantics.matlablink.CellArray" + data CellArray +importJava "org.simantics.matlablink.StructArray" + data StructArray + +importJava "org.simantics.matlablink.Engine" where + data Engine + + @JavaName close + closeEngine :: Engine -> () + + @JavaName evaluateMatlabExpression + executeMatlabExpression :: String -> () + + getMatlabArray :: String -> MatlabArray + getMatlabDoubleArray :: String -> DoubleArray + getMatlabCharacterArray :: String -> ChracterArray + getMatlabCellArray :: String -> CellArray + getMatlabStructArray :: String -> StructArray + + setMatlabArray :: String -> MatlabArray -> () + setMatlabDoubleArray :: String -> DoubleArray -> () + setMatlabCharacterArray :: String -> CharacterArray -> () + setMatlabCellArray :: String -> CellArray -> () + setMatlabStructArray :: String -> StructArray -> () + +importJava "org.simantics.matlablink.Matlab" where + @JavaName runWithEngine + runWithEngineF :: Engine -> (() -> a) -> a + + @JavaName runMatlab + runMatlabF :: File -> (() -> a) -> a + + matchMatlabArray :: a -> (Vector Double -> b) -> (String -> b) -> (Vector Dynamic -> b) -> (Map.T String (Vector Dynamic) -> b) -> b + + openEngine :: File -> Engine + +runWithEngine :: Engine -> a -> a +runWithEngine engine v = runWithEngineF engine (\_ -> v) + +runMatlab :: File -> a -> a +runMatlab wd v = runMatlabF wd (\_ -> v) + +evaluateMatlabExpression :: MatlabCompatible a => String -> a +evaluateMatlabExpression expression = do + executeMatlabExpression expression + getMatlabVariable "ans" + +class (Typeable a) => MatlabCompatible a where + getMatlabVariable :: String -> a + setMatlabVariable :: String -> a -> () + +instance MatlabCompatible (Vector Double) where + getMatlabVariable = getMatlabDoubleArray + setMatlabVariable name value = setMatlabDoubleArray name False value + +instance MatlabCompatible [Double] where + getMatlabVariable = vectorToList . getMatlabDoubleArray + setMatlabVariable name value = setMatlabDoubleArray name False (vector value) + +instance MatlabCompatible Double where + getMatlabVariable name = (getMatlabDoubleArray name)!0 + setMatlabVariable name value = setMatlabDoubleArray name False (vector [value]) + +instance MatlabCompatible String where + getMatlabVariable = getMatlabCharacterArray + setMatlabVariable = setMatlabCharacterArray + +instance MatlabCompatible (Vector Dynamic) where + getMatlabVariable = getMatlabCellArray + setMatlabVariable name value = setMatlabCellArray name False value + +instance MatlabCompatible Dynamic where + getMatlabVariable = getMatlabArray + setMatlabVariable = setMatlabArray + +instance MatlabCompatible (Dynamic, Dynamic) where + getMatlabVariable name = let + v = getMatlabCellArray name + in + (v!0, v!1) + + setMatlabVariable name (a, b) = setMatlabCellArray name False (vector [toDynamic a, toDynamic b]) diff --git a/org.simantics.matlablink/src/org/simantics/matlablink/Activator.java b/org.simantics.matlablink/src/org/simantics/matlablink/Activator.java new file mode 100644 index 0000000..641bd89 --- /dev/null +++ b/org.simantics.matlablink/src/org/simantics/matlablink/Activator.java @@ -0,0 +1,31 @@ +package org.simantics.matlablink; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + System.loadLibrary("jnimatlab"); + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/org.simantics.matlablink/src/org/simantics/matlablink/CellArray.java b/org.simantics.matlablink/src/org/simantics/matlablink/CellArray.java new file mode 100644 index 0000000..253ac04 --- /dev/null +++ b/org.simantics.matlablink/src/org/simantics/matlablink/CellArray.java @@ -0,0 +1,92 @@ +package org.simantics.matlablink; + +import java.util.Arrays; + +public class CellArray extends MatlabArray { + MatlabArray[] value; + int[] dims; + + public CellArray(int length) { + value = new MatlabArray[length]; + dims = new int[] {1, length}; + } + + public CellArray(int... dims) { + int nelem = 1; + for (int n : dims) nelem *= n; + + this.dims = dims; + value = new MatlabArray[nelem]; + } + + @Override + public int size() { + return value.length; + } + + @Override + public int[] dims() { + return dims; + } + + public void setCellItem(int index, MatlabArray v) { + value[index] = v; + } + + @Override + public boolean isCell() { + return true; + } + + @Override + public MatlabArray[] getCellValue() { + return value; + } + + public MatlabArray getCellItem(int index) { + return value[index]; + } + + public MatlabArray getCellItem(int i, int j) { + return value[i + dims[0] * j]; + } + + public MatlabArray getCellItem(int... k) { + if (k.length > dims.length) throw new IllegalArgumentException("Too many indexes for array of dimension " + dims.length); + + int s = 1; + int index = 0; + for (int l = 0; l < k.length; l++) { + index = index + s * k[l]; + s *= dims[l]; + } + + return value[index]; + } + + @Override + public boolean equals( Object obj ) { + return obj instanceof CellArray && + Arrays.equals(this.dims, ((CellArray)obj).dims) && + Arrays.equals(this.value, ((CellArray)obj).value); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{"); + for (int i = 0; i < Math.min(size(), 10); i++) { + if (i > 0) sb.append(", "); + sb.append(value[i]); + } + if (size() > 10) sb.append(", ..."); + sb.append(" ("); + for (int i = 0; i < dims.length; i++) { + if (i > 0) sb.append("x"); + sb.append(dims[i]); + } + sb.append(")}"); + + return sb.toString(); + } +} diff --git a/org.simantics.matlablink/src/org/simantics/matlablink/CharacterArray.java b/org.simantics.matlablink/src/org/simantics/matlablink/CharacterArray.java new file mode 100644 index 0000000..30995e6 --- /dev/null +++ b/org.simantics.matlablink/src/org/simantics/matlablink/CharacterArray.java @@ -0,0 +1,98 @@ +package org.simantics.matlablink; + +import java.util.Arrays; + +public class CharacterArray extends MatlabArray { + char[] value; // Content as UTF-16 bytes + int[] dims; + + public CharacterArray(char[] value) { + this.value = value; + dims = new int[] { 1, value.length }; + } + + public CharacterArray(String stringValue) { + this.value = stringValue.toCharArray(); + dims = new int[] { 1, value.length }; + } + + public CharacterArray(int dims[], char[] value) { + int nelem = 1; + for (int n : dims) nelem *= n; + + if (nelem != value.length) + throw new IllegalArgumentException("Array dimension and value mismatch"); + + this.value = value; + this.dims = dims; + } + + @Override + public int size() { + return value.length; + } + + @Override + public int[] dims() { + return dims; + } + + @Override + public boolean isCharacter() { + return true; + } + + @Override + public String getStringValue() { + return new String(value); + } + + public char[] getCharacters() { + return value; + } + + public char getCharacter(int index) { + return value[index]; + } + + public char getCharacter(int... is) { + if (is.length > dims.length) throw new IllegalArgumentException("Too many indexes for array of dimension " + dims.length); + + int index = 0; + int s = 1; + for (int k = 0; k < is.length; k++) { + index = index + s * is[k]; + s *= dims[k]; + } + + return value[index]; + } + + @Override + public boolean equals( Object obj ) { + return obj instanceof CharacterArray && + Arrays.equals(this.dims, ((CharacterArray)obj).dims) && + Arrays.equals(this.value, ((CharacterArray)obj).value); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("\""); + + for (int i = 0; i < Math.min(value.length, 160); i++) { + sb.append(value[i]); + } + if (value.length > 160) + sb.append("..."); + + sb.append("\"("); + for (int i = 0; i < dims.length; i++) { + if (i > 0) sb.append("x"); + sb.append(dims[i]); + } + sb.append(")"); + + return sb.toString(); + } +} diff --git a/org.simantics.matlablink/src/org/simantics/matlablink/DoubleArray.java b/org.simantics.matlablink/src/org/simantics/matlablink/DoubleArray.java new file mode 100644 index 0000000..b1fb893 --- /dev/null +++ b/org.simantics.matlablink/src/org/simantics/matlablink/DoubleArray.java @@ -0,0 +1,100 @@ +package org.simantics.matlablink; + +import java.util.Arrays; + +public class DoubleArray extends MatlabArray { + double[] value; + int[] dims; + + public DoubleArray(double[] value) { + this.value = value; + dims = new int[] { 1, value.length }; + } + + public DoubleArray(int m, int n, double[] value) { + if (m * n != value.length) + throw new IllegalArgumentException("Array dimension and value mismatch"); + + this.value = value; + this.dims = new int[] { m, n }; + } + + public DoubleArray(int[] dims, double[] value) { + int nelem = dims.length > 0 ? 1 : 0; + for (int n : dims) nelem *= n; + + if (nelem != value.length) + throw new IllegalArgumentException("Array dimension and value mismatch"); + + this.value = value; + this.dims = dims; + } + + @Override + public boolean isDouble() { + return true; + } + + @Override + public int size() { + return value.length; + } + + @Override + public int[] dims() { + return dims; + } + + @Override + public double[] getDoubleValue() { + return value; + } + + @Override + public double getDoubleValue(int index) { + return value[index]; + } + + public double getDoubleValue(int i, int j) { + return value[i + dims[0] * j]; + } + + public double getDoubleValue(int... k) { + if (k.length > dims.length) throw new IllegalArgumentException("Too many indexes for array of dimension " + dims.length); + + int s = 1; + int index = 0; + for (int l = 0; l < k.length; l++) { + index = index + s * k[l]; + s *= dims[l]; + } + + return value[index]; + } + + @Override + public boolean equals( Object obj ) { + return obj instanceof DoubleArray && + Arrays.equals(this.dims, ((DoubleArray)obj).dims) && + Arrays.equals(this.value, ((DoubleArray)obj).value); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("["); + for (int i = 0; i < Math.min(size(), 10); i++) { + if (i > 0) sb.append(", "); + sb.append(value[i]); + } + if (size() > 10) sb.append(", ..."); + sb.append(" ("); + for (int i = 0; i < dims.length; i++) { + if (i > 0) sb.append("x"); + sb.append(dims[i]); + } + sb.append(")]"); + + return sb.toString(); + } +} diff --git a/org.simantics.matlablink/src/org/simantics/matlablink/Engine.java b/org.simantics.matlablink/src/org/simantics/matlablink/Engine.java new file mode 100644 index 0000000..eb921fc --- /dev/null +++ b/org.simantics.matlablink/src/org/simantics/matlablink/Engine.java @@ -0,0 +1,246 @@ +package org.simantics.matlablink; + +import java.io.Closeable; +import java.io.IOException; + +public class Engine implements Closeable { + private long engineId; + + static { + try { + System.loadLibrary("jnimatlab"); + } catch(java.lang.UnsatisfiedLinkError e) { + System.out.println( "Error loading jnimatlab.dll: " + e.getMessage() ); + } + } + + /** + * Not public, use Matlab.openEngine() + */ + Engine(String workingDirectory) { + engineId = openMatlabEngineImpl(workingDirectory); + } + + /** + * Is the Matlab Engine connection open? + */ + public boolean isOpen() { + return engineId != 0; + } + + /** + * Close the Matlab Engine connection + */ + @Override + public void close() throws IOException { + long id = engineId; + engineId = 0; + closeMatlabEngineImpl(id); + } + + /** + * Get the value of a Matlab variable. + * + * The return type depends on the type of the Matlab variable, and + * matches the return type of the corresponding type-specific access + * function. + */ + public MatlabArray getMatlabArray(String variableName) { + if (variableName == null || variableName.isEmpty()) + throw new IllegalArgumentException("Invalid Matlab variable name \'" + variableName + "\'"); + + MatlabArray result; + synchronized ( this ) { + result = getMatlabArrayImpl(engineId, variableName); + } + + return result; + } + + /** + * Set the value of a Matlab variable. + * + * The value must be of a Java type that is supported by one of the type-specific + * access functions. An exception is thrown, if the value is not of a recognized type. + */ + public void setMatlabArray(String variableName, MatlabArray value) { + if (value == null) + throw new IllegalArgumentException("Invalid Matlab array value given"); + + int result; + synchronized ( this ) { + result = setMatlabArrayImpl(engineId, variableName, value); + } + + if (result != 0) { + throw new RuntimeException("Setting Matlab variable value failed"); + } + } + + /** + * Get the value of a Matlab double array variable. + */ + public DoubleArray getMatlabDoubleArray(String variableName) { + if (variableName == null || variableName.isEmpty()) + throw new IllegalArgumentException("Invalid Matlab variable name \'" + variableName + "\'"); + + DoubleArray result; + synchronized ( this ) { + result = getMatlabDoubleArrayImpl(engineId, variableName); + } + + return result; + } + + /** + * Set the value of a Matlab variable to a double array. + */ + public void setMatlabDoubleArray(String variableName, DoubleArray value) { + if (value == null) + throw new IllegalArgumentException("Invalid Matlab array value given"); + + int result; + synchronized ( this ) { + result = setMatlabDoubleArrayImpl(engineId, variableName, value); + } + + if (result != 0) { + throw new RuntimeException("Setting Matlab variable value failed"); + } + } + + /** + * Get the value of a Matlab cell array variable. + */ + public CellArray getMatlabCellArray(String variableName) { + if (variableName == null || variableName.isEmpty()) + throw new IllegalArgumentException("Invalid Matlab variable name \'" + variableName + "\'"); + + CellArray result; + synchronized ( this ) { + result = getMatlabCellArrayImpl(engineId, variableName); + } + + return result; + } + + /** + * Set the value of a Matlab variable to a cell array. + */ + public void setMatlabCellArray(String variableName, CellArray value) { + if (value == null) + throw new IllegalArgumentException("Invalid Matlab array value given"); + + int result; + synchronized ( this ) { + result = setMatlabCellArrayImpl(engineId, variableName, value); + } + + if (result != 0) { + throw new RuntimeException("Setting Matlab variable value failed"); + } + } + + /** + * Get the value of a Matlab character array variable. + */ + public CharacterArray getMatlabCharacterArray(String variableName) { + if (variableName == null || variableName.isEmpty()) + throw new IllegalArgumentException("Invalid Matlab variable name \'" + variableName + "\'"); + + CharacterArray result; + synchronized ( this ) { + result = getMatlabCharacterArrayImpl(engineId, variableName); + } + + return result; + } + + /** + * Set the value of a Matlab variable to a character array. + */ + public void setMatlabCharacterArray(String variableName, CharacterArray value) { + if (value == null) + throw new IllegalArgumentException("Invalid Matlab array value given"); + + int result; + synchronized ( this ) { + result = setMatlabCharacterArrayImpl(engineId, variableName, value); + } + + if (result != 0) { + throw new RuntimeException("Setting Matlab variable value failed"); + } + } + + /** + * Get the value of a Matlab struct array variable. + */ + public StructArray getMatlabStructArray(String variableName) { + if (variableName == null || variableName.isEmpty()) + throw new IllegalArgumentException("Invalid Matlab variable name \'" + variableName + "\'"); + + StructArray result; + synchronized ( this ) { + result = getMatlabStructArrayImpl(engineId, variableName); + } + + return result; + } + + /** + * Set the value of a Matlab variable to a struct array. + * + * The given map object must contain array of values of equal length and type, which + * must be suitable as input any of the type-specific access functions. + * + * A row vector is created. + */ + public void setMatlabStructArray(String variableName, StructArray value) { + if (value == null) + throw new IllegalArgumentException("Invalid Matlab array value given"); + + int result; + synchronized ( this ) { + result = setMatlabStructArrayImpl(engineId, variableName, value); + } + + if (result != 0) { + throw new RuntimeException("Setting Matlab variable value failed"); + } + } + + /** + * Evaluate a Matlab expression. + */ + public void evaluateMatlabExpression(String expression) { + int result; + synchronized ( this ) { + result = evaluateMatlabExpressionImpl(engineId, expression); + } + + if (result != 0) { + throw new RuntimeException("Evaluation of Matlab expression failed"); + } + } + + private static native long openMatlabEngineImpl(String workingDirectory); + private static native void closeMatlabEngineImpl(long engineId); + + private static native int evaluateMatlabExpressionImpl(long engineId, String expression); + + private static native MatlabArray getMatlabArrayImpl(long engineId, String variableName); + private static native int setMatlabArrayImpl(long engineId, String variableName, MatlabArray value); + + private static native DoubleArray getMatlabDoubleArrayImpl(long engineId, String variableName); + private static native int setMatlabDoubleArrayImpl(long engineId, String variableName, DoubleArray value); + + private static native CellArray getMatlabCellArrayImpl(long engineId, String variableName); + private static native int setMatlabCellArrayImpl(long engineId, String variableName, CellArray value); + + private static native CharacterArray getMatlabCharacterArrayImpl(long engineId, String variableName); + private static native int setMatlabCharacterArrayImpl(long engineId, String variableName, CharacterArray value); + + private static native StructArray getMatlabStructArrayImpl(long engineId, String variableName); + private static native int setMatlabStructArrayImpl(long engineId, String variableName, StructArray value); +} diff --git a/org.simantics.matlablink/src/org/simantics/matlablink/Matlab.java b/org.simantics.matlablink/src/org/simantics/matlablink/Matlab.java new file mode 100644 index 0000000..9d4adcf --- /dev/null +++ b/org.simantics.matlablink/src/org/simantics/matlablink/Matlab.java @@ -0,0 +1,67 @@ +package org.simantics.matlablink; + +import java.io.File; +import java.io.IOException; +import java.util.Map; + +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.function.Function; +import org.simantics.scl.runtime.tuple.Tuple0; + +public class Matlab { + public static final String ENGINE = "Simantics/Matlab/Matlab"; + + public static Engine openEngine(File workingDirectory) { + if (workingDirectory == null || !workingDirectory.exists() || !workingDirectory.isDirectory()) { + throw new IllegalArgumentException("Working directory is not an existing directory"); + } + + Engine engine = new Engine(workingDirectory.getAbsolutePath()); + if (!engine.isOpen()) + throw new RuntimeException("Opening Matlab engine failed"); + + return engine; + } + + @SuppressWarnings( "unchecked" ) + public static Object runMatlab(File workingDirectory, @SuppressWarnings("rawtypes") Function fun) { + SCLContext context = SCLContext.getCurrent(); + Engine oldEngine = (Engine)context.get(ENGINE); + try (Engine newEngine = openEngine(workingDirectory)) { + context.put(ENGINE, newEngine); + return fun.apply(Tuple0.INSTANCE); + } catch ( IOException e ) { + throw new RuntimeException(e); + } + finally { + context.put(ENGINE, oldEngine); + } + } + + @SuppressWarnings( "unchecked" ) + public static Object runWithEngine(Engine engine, @SuppressWarnings("rawtypes") Function fun) { + SCLContext context = SCLContext.getCurrent(); + Engine oldEngine = (Engine)context.get(ENGINE); + try { + context.put(ENGINE, engine); + return fun.apply(Tuple0.INSTANCE); + } + finally { + context.put(ENGINE, oldEngine); + } + } + + @SuppressWarnings( { "unchecked", "rawtypes" } ) + public static Object matchMatlabArray(Object array, Function doubleFun, Function stringFun, Function cellFun, Function structFun) { + if (array instanceof double[]) + return doubleFun.apply(array); + else if (array instanceof String) + return stringFun.apply(array); + else if (array instanceof Object[]) + return cellFun.apply(array); + else if (array instanceof Map) + return structFun.apply(array); + else + return null; + } +} diff --git a/org.simantics.matlablink/src/org/simantics/matlablink/MatlabArray.java b/org.simantics.matlablink/src/org/simantics/matlablink/MatlabArray.java new file mode 100644 index 0000000..25244e4 --- /dev/null +++ b/org.simantics.matlablink/src/org/simantics/matlablink/MatlabArray.java @@ -0,0 +1,70 @@ +package org.simantics.matlablink; + +import java.util.Map; + +public abstract class MatlabArray { + public boolean isDouble() { + return false; + } + + public boolean isCharacter() { + return false; + } + + public boolean isCell() { + return false; + } + + public boolean isStruct() { + return false; + } + + public int size() { + return 0; + } + + public int[] dims() { + return null; + } + + public double[] getDoubleValue() { + return null; + } + + public double getDoubleValue(int index) { + return 0.0; + } + + public String getStringValue() { + return null; + } + + public MatlabArray[] getCellValue() { + return null; + } + + public MatlabArray getCellItem(int index) { + return null; + } + + public MatlabArray getField(int index, String fieldName) { + return null; + } + + public Map getStructItem(int index) { + return null; + } + + public interface Visitor { + public void visit(DoubleArray value); + public void visit(CellArray value); + public void visit(CharacterArray value); + public void visit(StructArray value); + } + + @Override + abstract public boolean equals( Object obj ); + + @Override + abstract public String toString(); +} diff --git a/org.simantics.matlablink/src/org/simantics/matlablink/StructArray.java b/org.simantics.matlablink/src/org/simantics/matlablink/StructArray.java new file mode 100644 index 0000000..a0f4043 --- /dev/null +++ b/org.simantics.matlablink/src/org/simantics/matlablink/StructArray.java @@ -0,0 +1,148 @@ +package org.simantics.matlablink; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +public class StructArray extends MatlabArray { + int size; + Map fields; + int[] dims; + + public StructArray(int size, String[] fields) { + this.size = size; + this.dims = new int[] {1, size}; + this.fields = new HashMap(); + for (String name : fields) { + this.fields.put(name, new MatlabArray[size]); + } + } + + public StructArray(int size, Collection fields) { + this.size = size; + this.dims = new int[] {1, size}; + this.fields = new HashMap(); + for (String name : fields) { + this.fields.put(name, new MatlabArray[size]); + } + } + + public StructArray(int[] dims, String[] fields) { + this.dims = dims; + int size = 1; + for (int n : dims) size *= n; + this.size = size; + + this.fields = new HashMap(); + for (String name : fields) { + this.fields.put(name, new MatlabArray[size]); + } + } + + public StructArray(int[] dims, Collection fields) { + this.dims = dims; + int size = 1; + for (int n : dims) size *= n; + this.size = size; + + this.fields = new HashMap(); + for (String name : fields) { + this.fields.put(name, new MatlabArray[size]); + } + } + + @Override + public boolean isStruct() { + return true; + } + + @Override + public int size() { + return size; + } + + @Override + public int[] dims() { + return dims; + } + + public String[] getFields() { + return fields.keySet().toArray(new String[fields.size()]); + } + + @Override + public MatlabArray getField(int index, String fieldName) { + MatlabArray[] value = fields.get( fieldName ); + return value != null ? value[index] : null; + } + + public MatlabArray getField(String fieldName, int... is) { + int index = 0; + int s = 1; + for (int k = 0; k < is.length; k++) { + index = index + s * is[k]; + s *= dims[k]; + } + + return getField(index, fieldName); + } + + public void setField(int index, String fieldName, MatlabArray v) { + MatlabArray[] value = fields.get( fieldName ); + if (value == null) { + value = new MatlabArray[size]; + value[index] = v; + fields.put( fieldName, value ); + } + value[index] = v; + } + + public void setField(String fieldName, MatlabArray v, int... is) { + int index = 0; + int s = 1; + for (int k = 0; k < is.length; k++) { + index = index + s * is[k]; + s *= dims[k]; + } + + setField(index, fieldName, v); + } + + @Override + public boolean equals( Object obj ) { + return obj instanceof StructArray && + Arrays.equals(this.dims, ((StructArray)obj).dims) && + fieldsEqual(this.fields, ((StructArray)obj).fields); + } + + private static boolean fieldsEqual( Map f1, Map f2 ) { + if (!f1.keySet().equals(f2.keySet())) + return false; + return Arrays.deepEquals(f1.values().toArray(), f2.values().toArray()); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("{"); + Set keys = fields.keySet(); + Iterator iter = keys.iterator(); + for (int i = 0; i < fields.entrySet().size(); i++) { + String key = iter.next(); + if (i > 0) sb.append(", "); + sb.append(key); + } + + sb.append(" ("); + for (int i = 0; i < dims.length; i++) { + if (i > 0) sb.append("x"); + sb.append( dims[i] ); + } + sb.append(")}"); + + return sb.toString(); + } +} diff --git a/org.simantics.matlablink/test/org/simantics/matlablink/test/TestMatlabEngine.java b/org.simantics.matlablink/test/org/simantics/matlablink/test/TestMatlabEngine.java new file mode 100644 index 0000000..cae75fc --- /dev/null +++ b/org.simantics.matlablink/test/org/simantics/matlablink/test/TestMatlabEngine.java @@ -0,0 +1,267 @@ +package org.simantics.matlablink.test; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.nio.file.Files; +import java.nio.file.Path; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.simantics.matlablink.CellArray; +import org.simantics.matlablink.CharacterArray; +import org.simantics.matlablink.DoubleArray; +import org.simantics.matlablink.Engine; +import org.simantics.matlablink.Matlab; +import org.simantics.matlablink.MatlabArray; +import org.simantics.matlablink.StructArray; + +public class TestMatlabEngine { + + Engine engine; + Path tempDir; + + @BeforeClass + public void setUp() throws Exception { + tempDir = Files.createTempDirectory( "testMatlabEngine" ); + engine = Matlab.openEngine(tempDir.toFile()); + } + + @AfterClass + public void tearDown() throws Exception { + engine.close(); + tempDir.toFile().delete(); + } + + @Test + public void testDoubleArray() { + double[] values = new double[] { 1, 2, 3 }; + engine.setMatlabDoubleArray("foo", new DoubleArray(values)); + DoubleArray returnedValues = engine.getMatlabDoubleArray("foo"); + + assertArrayEquals(new int[] { 1, 3 }, returnedValues.dims()); + assertArrayEquals(values, returnedValues.getDoubleValue(), 0.0); + } + + @Test + public void testCharacterArray() { + String value = "Hello world! (�ん���世界!)"; + engine.setMatlabCharacterArray("foo", new CharacterArray(value)); + CharacterArray returnedValue = engine.getMatlabCharacterArray("foo"); + + assertEquals(value, returnedValue.getStringValue()); + } + + @Test + public void testCellArray() { + CellArray value = new CellArray( 2 ); + value.setCellItem(0, new DoubleArray(new double[] { 1, 2 })); + value.setCellItem(1, new CharacterArray("Booyah!")); + + engine.setMatlabCellArray("foo", value); + CellArray returnedValues = engine.getMatlabCellArray("foo"); + + assertEquals(value, returnedValues); + } + + @Test + public void testStructArray() { + String[] fields = new String[] {"field_1", "field_2"}; + StructArray value = new StructArray(2, fields); + value.setField(0, fields[0], new DoubleArray(new double[] { 1, 2, 3, 4 })); + value.setField(1, fields[0], new DoubleArray(new double[] { 2, 4, 6, })); + value.setField(0, fields[1], new CharacterArray("foo")); + value.setField(1, fields[1], new CharacterArray("bar")); + + engine.setMatlabStructArray("foo", value); + StructArray returnedValues = engine.getMatlabStructArray("foo"); + + assertEquals(value, returnedValues); + } + + @Test + public void testEvaluation1() { + engine.evaluateMatlabExpression("bar = [1 2 3];"); + DoubleArray returnedValues = engine.getMatlabDoubleArray("bar"); + + assertArrayEquals(new double[] {1, 2, 3}, returnedValues.getDoubleValue(), 0.0); + } + + @Test + public void testEvaluation2() { + engine.setMatlabDoubleArray("foo", new DoubleArray(new double[] { 1, 2, 3 })); + engine.evaluateMatlabExpression("bar = foo + 1;"); + DoubleArray returnedValues = engine.getMatlabDoubleArray("bar"); + + assertArrayEquals(new double[] {2, 3, 4}, returnedValues.getDoubleValue(), 0.0); + } + + @Test + public void testIncompatible1() { + engine.evaluateMatlabExpression("a = {'foo', 'bar'};"); + try { + engine.getMatlabDoubleArray("a"); + fail("Expected exception"); + } catch (Exception e) { + assertEquals( "Variable not a double array", e.getMessage() ); + } + } + + @Test + public void testIncompatible2() { + engine.evaluateMatlabExpression("a = {'foo', 'bar'};"); + try { + engine.getMatlabCharacterArray("a"); + fail("Expected exception"); + } catch (Exception e) { + assertEquals( "Variable not a character array", e.getMessage() ); + } + } + + @Test + public void testIncompatible3() { + engine.evaluateMatlabExpression("a = {'foo', 'bar'};"); + try { + engine.getMatlabStructArray("a"); + fail("Expected exception"); + } catch (Exception e) { + assertEquals( "Variable not a struct array", e.getMessage() ); + } + } + + @Test + public void testIncompatible4() { + engine.evaluateMatlabExpression("a = [1 2];"); + try { + engine.getMatlabCellArray("a"); + fail("Expected exception"); + } catch (Exception e) { + assertEquals( "Variable not a cell array", e.getMessage() ); + } + } + + + @Test + public void testIncompatible5() { + engine.evaluateMatlabExpression("a = [1 2];"); + try { + engine.getMatlabCharacterArray("a"); + fail("Expected exception"); + } catch (Exception e) { + assertEquals( "Variable not a character array", e.getMessage() ); + } + } + + @Test + public void testIncompatible6() { + engine.evaluateMatlabExpression("a = [1 2];"); + try { + engine.getMatlabStructArray("a"); + fail("Expected exception"); + } catch (Exception e) { + assertEquals( "Variable not a struct array", e.getMessage() ); + } + } + + @Test + public void testIncompatible7() { + engine.evaluateMatlabExpression("a = 'foobar';"); + try { + engine.getMatlabDoubleArray("a"); + fail("Expected exception"); + } catch (Exception e) { + assertEquals( "Variable not a double array", e.getMessage() ); + } + } + + @Test + public void testIncompatible8() { + engine.evaluateMatlabExpression("a = 'foobar';"); + try { + engine.getMatlabCellArray("a"); + fail("Expected exception"); + } catch (Exception e) { + assertEquals( "Variable not a cell array", e.getMessage() ); + } + } + + @Test + public void testIncompatible9() { + engine.evaluateMatlabExpression("a = 'foobar';"); + try { + engine.getMatlabStructArray("a"); + fail("Expected exception"); + } catch (Exception e) { + assertEquals( "Variable not a struct array", e.getMessage() ); + } + } + + @Test + public void testIncompatible10() { + engine.evaluateMatlabExpression("a = []; a.field = 1;"); + try { + engine.getMatlabDoubleArray("a"); + fail("Expected exception"); + } catch (Exception e) { + assertEquals( "Variable not a double array", e.getMessage() ); + } + } + + @Test + public void testIncompatible11() { + engine.evaluateMatlabExpression("a = []; a.field = 1;"); + try { + engine.getMatlabCharacterArray("a"); + fail("Expected exception"); + } catch (Exception e) { + assertEquals( "Variable not a character array", e.getMessage() ); + } + } + + @Test + public void testIncompatible12() { + engine.evaluateMatlabExpression("a = []; a.field = 1;"); + try { + engine.getMatlabCellArray("a"); + fail("Expected exception"); + } catch (Exception e) { + assertEquals( "Variable not a cell array", e.getMessage() ); + } + } + + @Test + public void testGeneric1() { + engine.evaluateMatlabExpression("a = [1, 2, 3, 4];"); + MatlabArray result = engine.getMatlabArray("a"); + assertTrue(result instanceof DoubleArray); + assertArrayEquals(new double[] { 1, 2, 3, 4 }, result.getDoubleValue(), 0.0); + } + + @Test + public void testGeneric2() { + engine.evaluateMatlabExpression("a = 'foobar';"); + MatlabArray result = engine.getMatlabArray("a"); + assertTrue(result instanceof CharacterArray); + assertEquals("foobar", result.getStringValue()); + } + + @Test + public void testGeneric3() { + engine.evaluateMatlabExpression("a = { struct('foo', 1), 'bar' };"); + MatlabArray a = engine.getMatlabArray("a"); + + assertTrue(a instanceof CellArray); + MatlabArray a_1 = a.getCellItem(0); + MatlabArray a_2 = a.getCellItem(1); + assertTrue(a_1 instanceof StructArray); + assertTrue(a_2 instanceof CharacterArray); + MatlabArray a_1_foo = a_1.getField(0, "foo"); + assertTrue(a_1_foo instanceof DoubleArray); + assertEquals(1, a_1_foo.size()); + assertArrayEquals(new double[] {1}, a_1_foo.getDoubleValue(), 0.0); + assertEquals("bar", a_2.getStringValue()); + } +}