]> gerrit.simantics Code Review - simantics/matlab.git/commitdiff
Three new projects for a Matlab integration feature. 43/343/1
authorReino Ruusu <reino.ruusu@vtt.fi>
Fri, 3 Mar 2017 11:16:25 +0000 (13:16 +0200)
committerReino Ruusu <reino.ruusu@vtt.fi>
Fri, 3 Mar 2017 11:16:25 +0000 (13:16 +0200)
Change-Id: I27efcee2d6d5a8073a419af6ccd76343cbe3fb40

34 files changed:
org.simantics.matlablink.feature/.project [new file with mode: 0644]
org.simantics.matlablink.feature/build.properties [new file with mode: 0644]
org.simantics.matlablink.feature/feature.xml [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/.classpath [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/.project [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/.settings/org.eclipse.pde.core.prefs [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/META-INF/MANIFEST.MF [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/bin/.gitignore [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/build.properties [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/jnimatlab.dll [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/src/jni.h [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/src/jni_md.h [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/src/jnimatlab.vcxproj [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/src/jnimatlab.vcxproj.filters [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/src/sclmat.c [new file with mode: 0644]
org.simantics.matlablink.win32.x86_64/src/sclmat.h [new file with mode: 0644]
org.simantics.matlablink/.classpath [new file with mode: 0644]
org.simantics.matlablink/.gitignore [new file with mode: 0644]
org.simantics.matlablink/.project [new file with mode: 0644]
org.simantics.matlablink/.settings/org.eclipse.core.resources.prefs [new file with mode: 0644]
org.simantics.matlablink/.settings/org.eclipse.jdt.core.prefs [new file with mode: 0644]
org.simantics.matlablink/META-INF/MANIFEST.MF [new file with mode: 0644]
org.simantics.matlablink/build.properties [new file with mode: 0644]
org.simantics.matlablink/scl/Simantics/Matlab.scl [new file with mode: 0644]
org.simantics.matlablink/src/org/simantics/matlablink/Activator.java [new file with mode: 0644]
org.simantics.matlablink/src/org/simantics/matlablink/CellArray.java [new file with mode: 0644]
org.simantics.matlablink/src/org/simantics/matlablink/CharacterArray.java [new file with mode: 0644]
org.simantics.matlablink/src/org/simantics/matlablink/DoubleArray.java [new file with mode: 0644]
org.simantics.matlablink/src/org/simantics/matlablink/Engine.java [new file with mode: 0644]
org.simantics.matlablink/src/org/simantics/matlablink/Matlab.java [new file with mode: 0644]
org.simantics.matlablink/src/org/simantics/matlablink/MatlabArray.java [new file with mode: 0644]
org.simantics.matlablink/src/org/simantics/matlablink/StructArray.java [new file with mode: 0644]
org.simantics.matlablink/test/org/simantics/matlablink/test/TestMatlabEngine.java [new file with mode: 0644]

diff --git a/org.simantics.matlablink.feature/.project b/org.simantics.matlablink.feature/.project
new file mode 100644 (file)
index 0000000..d348cac
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.matlablink.feature</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.FeatureBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.FeatureNature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/org.simantics.matlablink.feature/build.properties b/org.simantics.matlablink.feature/build.properties
new file mode 100644 (file)
index 0000000..82ab19c
--- /dev/null
@@ -0,0 +1 @@
+bin.includes = feature.xml\r
diff --git a/org.simantics.matlablink.feature/feature.xml b/org.simantics.matlablink.feature/feature.xml
new file mode 100644 (file)
index 0000000..292ec4a
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<feature\r
+      id="fi.vtt.matlablink"\r
+      label="Matlablink"\r
+      version="1.0.0.qualifier">\r
+\r
+   <description url="http://www.example.com/description">\r
+      [Enter Feature Description here.]\r
+   </description>\r
+\r
+   <copyright url="http://www.example.com/copyright">\r
+      [Enter Copyright Description here.]\r
+   </copyright>\r
+\r
+   <license url="http://www.example.com/license">\r
+      [Enter License Description here.]\r
+   </license>\r
+\r
+   <requires>\r
+      <import plugin="org.junit"/>\r
+      <import plugin="org.eclipse.osgi"/>\r
+      <import plugin="org.simantics.scl.runtime"/>\r
+      <import plugin="gnu.trove3" version="3.0.3" match="greaterOrEqual"/>\r
+      <import plugin="fi.vtt.matlablink" version="1.0.0" match="greaterOrEqual"/>\r
+   </requires>\r
+\r
+   <plugin\r
+         id="fi.vtt.matlablink"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         unpack="false"/>\r
+\r
+   <plugin\r
+         id="fi.vtt.matlablink.win32.x86_64"\r
+         download-size="0"\r
+         install-size="0"\r
+         version="0.0.0"\r
+         fragment="true"\r
+         unpack="false"/>\r
+\r
+</feature>\r
diff --git a/org.simantics.matlablink.win32.x86_64/.classpath b/org.simantics.matlablink.win32.x86_64/.classpath
new file mode 100644 (file)
index 0000000..b862a29
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/org.simantics.matlablink.win32.x86_64/.project b/org.simantics.matlablink.win32.x86_64/.project
new file mode 100644 (file)
index 0000000..152bbee
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.matlablink.win32.x86_64</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
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 (file)
index 0000000..295926d
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.8\r
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 (file)
index 0000000..d711c29
--- /dev/null
@@ -0,0 +1,4 @@
+eclipse.preferences.version=1\r
+pluginProject.equinox=false\r
+pluginProject.extensions=false\r
+resolve.requirebundle=false\r
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 (file)
index 0000000..83b191a
--- /dev/null
@@ -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 (file)
index 0000000..2fc9e08
--- /dev/null
@@ -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 (file)
index 0000000..2d0d26e
--- /dev/null
@@ -0,0 +1,8 @@
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+               .,\\r
+               jnimatlab.dll,\\r
+               jnipython.dll\r
+src.includes = jnimatlab.dll,\\r
+               jnipython.dll\r
diff --git a/org.simantics.matlablink.win32.x86_64/jnimatlab.dll b/org.simantics.matlablink.win32.x86_64/jnimatlab.dll
new file mode 100644 (file)
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 (file)
index 0000000..f53476c
--- /dev/null
@@ -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 <stdio.h>
+#include <stdarg.h>
+
+/* 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 (file)
index 0000000..9f0cfa4
--- /dev/null
@@ -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 (file)
index 0000000..8aca77e
--- /dev/null
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup Label="ProjectConfigurations">\r
+    <ProjectConfiguration Include="Debug|Win32">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Debug|x64">\r
+      <Configuration>Debug</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|Win32">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>Win32</Platform>\r
+    </ProjectConfiguration>\r
+    <ProjectConfiguration Include="Release|x64">\r
+      <Configuration>Release</Configuration>\r
+      <Platform>x64</Platform>\r
+    </ProjectConfiguration>\r
+  </ItemGroup>\r
+  <PropertyGroup Label="Globals">\r
+    <ProjectGuid>{1C933BCE-5239-49A7-A553-6F9993223A2F}</ProjectGuid>\r
+    <RootNamespace>jnimatlab</RootNamespace>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseDebugLibraries>true</UseDebugLibraries>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseDebugLibraries>true</UseDebugLibraries>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseDebugLibraries>false</UseDebugLibraries>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+    <ConfigurationType>DynamicLibrary</ConfigurationType>\r
+    <UseDebugLibraries>false</UseDebugLibraries>\r
+    <WholeProgramOptimization>true</WholeProgramOptimization>\r
+    <CharacterSet>MultiByte</CharacterSet>\r
+  </PropertyGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+  <ImportGroup Label="ExtensionSettings">\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+  </ImportGroup>\r
+  <PropertyGroup Label="UserMacros" />\r
+  <PropertyGroup />\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>.;C:\Program Files (x86)\MATLAB\R2014b\extern\include</AdditionalIncludeDirectories>\r
+    </ClCompile>\r
+    <Link>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <AdditionalLibraryDirectories>C:\Program Files (x86)\MATLAB\R2014b\extern\lib\win32\microsoft</AdditionalLibraryDirectories>\r
+      <AdditionalDependencies>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)</AdditionalDependencies>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>Disabled</Optimization>\r
+      <AdditionalIncludeDirectories>.;C:\Program Files (x86)\MATLAB\R2014b\extern\include</AdditionalIncludeDirectories>\r
+    </ClCompile>\r
+    <Link>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <AdditionalLibraryDirectories>C:\Program Files\MATLAB\R2014b\extern\lib\win64\microsoft</AdditionalLibraryDirectories>\r
+      <AdditionalDependencies>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)</AdditionalDependencies>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <AdditionalIncludeDirectories>.;C:\Program Files (x86)\MATLAB\R2014b\extern\include</AdditionalIncludeDirectories>\r
+    </ClCompile>\r
+    <Link>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <AdditionalLibraryDirectories>C:\Program Files (x86)\MATLAB\R2014b\extern\lib\win32\microsoft</AdditionalLibraryDirectories>\r
+      <AdditionalDependencies>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)</AdditionalDependencies>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+    <ClCompile>\r
+      <WarningLevel>Level3</WarningLevel>\r
+      <Optimization>MaxSpeed</Optimization>\r
+      <FunctionLevelLinking>true</FunctionLevelLinking>\r
+      <IntrinsicFunctions>true</IntrinsicFunctions>\r
+      <AdditionalIncludeDirectories>.;C:\Program Files (x86)\MATLAB\R2014b\extern\include</AdditionalIncludeDirectories>\r
+    </ClCompile>\r
+    <Link>\r
+      <GenerateDebugInformation>true</GenerateDebugInformation>\r
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+      <OptimizeReferences>true</OptimizeReferences>\r
+      <AdditionalLibraryDirectories>C:\Program Files\MATLAB\R2014b\extern\lib\win64\microsoft</AdditionalLibraryDirectories>\r
+      <AdditionalDependencies>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)</AdditionalDependencies>\r
+    </Link>\r
+  </ItemDefinitionGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="sclmat.c" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="sclmat.h" />\r
+  </ItemGroup>\r
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+  <ImportGroup Label="ExtensionTargets">\r
+  </ImportGroup>\r
+</Project>
\ 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 (file)
index 0000000..9993981
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <ItemGroup>\r
+    <Filter Include="Source Files">\r
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r
+    </Filter>\r
+    <Filter Include="Header Files">\r
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>\r
+    </Filter>\r
+    <Filter Include="Resource Files">\r
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r
+    </Filter>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClCompile Include="sclmat.c">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <ClInclude Include="sclmat.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+  </ItemGroup>\r
+</Project>
\ 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 (file)
index 0000000..f2dab65
--- /dev/null
@@ -0,0 +1,791 @@
+///////////////////////////////////////////////////////\r
+//                                                   //\r
+//   VTT Technical Research Centre of Finland LTD    //\r
+//   For internal use only. Do not redistribute.     //\r
+//                                                   //\r
+//   Authors:                                        //\r
+//       Antton Tapani    ext-antton.tapani@vtt.fi   //\r
+//                                                   //\r
+//   Last modified by Antton Tapani    9.2016        //\r
+//                                                   //\r
+///////////////////////////////////////////////////////\r
+\r
+#include <windows.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <direct.h>\r
+#include "engine.h"\r
+#include <jni.h>\r
+\r
+#pragma warning(disable: 4996)\r
+\r
+#define UTF8FEATURE "feature('DefaultCharacterSet', 'UTF-8')"\r
+\r
+#define BUFSIZE 1000\r
+\r
+#define MAXJSIZE MAXLONG\r
+#define MAXJINT MAXLONG\r
+\r
+#define tojsize(x) ((jsize)(min((x), MAXJSIZE)))\r
+#define tojint(x) ((jint)(min((x), MAXJINT)))\r
+\r
+jobject getJavaStructArray(JNIEnv *env, mxArray *matlabArray);\r
+jobject getJavaCharacterArray(JNIEnv *env, mxArray *matlabArray);\r
+jobject getJavaDoubleArray(JNIEnv *env, mxArray *matlabArray);\r
+jobject getJavaCellArray(JNIEnv *env, mxArray *matlabArray);\r
+jobject getJavaArray(JNIEnv *env, mxArray *item);\r
+\r
+mxArray *getMatlabArray(JNIEnv *env, jobject item);\r
+mxArray *getMatlabDoubleArray(JNIEnv *env, jobject value);\r
+mxArray *getMatlabCharacterArray(JNIEnv *env, jobject value);\r
+mxArray *getMatlabStructArray(JNIEnv *env, jobject value);\r
+mxArray *getMatlabCellArray(JNIEnv *env, jobject value);\r
+\r
+jint throwException( JNIEnv *env, char *className, char *message )\r
+{\r
+    jclass exClass = (*env)->FindClass( env, className);\r
+    if (exClass == NULL) {\r
+        return 0;\r
+    }\r
+\r
+    return (*env)->ThrowNew( env, exClass, message );\r
+}\r
+\r
+jint throwIllegalArgumentException( JNIEnv *env, char *message ) {\r
+       return throwException( env, "java/lang/IllegalArgumentException", message );\r
+}\r
+\r
+/**\r
+ * Get the dimensions of a Matlab array as a Java integer[].\r
+ * The value pointed to by nelems is set to the total number of elements int\r
+ * the array.\r
+ */\r
+jintArray getMatlabArrayDims(JNIEnv *env, mxArray *matlabArray) {\r
+       int i;\r
+\r
+       size_t ndims = mxGetNumberOfDimensions(matlabArray);\r
+       const size_t *dims = mxGetDimensions(matlabArray);\r
+\r
+       jintArray jdims = (*env)->NewIntArray(env, tojsize(ndims));\r
+\r
+       for (i = 0; i < ndims; i++) {\r
+               jsize dim = tojsize(dims[i]);\r
+               (*env)->SetIntArrayRegion(env, jdims, i, 1, &dim);\r
+       }\r
+\r
+       return jdims;\r
+}\r
+\r
+/**\r
+ * Get the contents of a Matlab double array as (Java) double[].\r
+ */\r
+jobject getJavaDoubleArray(JNIEnv *env, mxArray *matlabArray) {\r
+       jclass doubleArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/DoubleArray");\r
+       jmethodID constructor = (*env)->GetMethodID(env, doubleArrayClass, "<init>", "([I[D)V");\r
+\r
+       jsize nelems = tojsize(mxGetNumberOfElements(matlabArray));\r
+       jdoubleArray values = (*env)->NewDoubleArray(env, nelems);\r
+       double *contents = mxGetPr(matlabArray);\r
+       (*env)->SetDoubleArrayRegion(env, values, 0, nelems, contents);\r
+\r
+       {\r
+               jintArray jdims = getMatlabArrayDims(env, matlabArray);\r
+               jobject result = (*env)->NewObject(env, doubleArrayClass, constructor, jdims, values);\r
+               return result;\r
+       }\r
+}\r
+\r
+/**\r
+ * Get the contents of a Matlab character array as java.lang.String.\r
+ */\r
+jobject getJavaCharacterArray(JNIEnv *env, mxArray *matlabArray) {\r
+       jclass characterArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/CharacterArray");\r
+       jmethodID constructor = (*env)->GetMethodID(env, characterArrayClass, "<init>", "([I[C)V");\r
+\r
+       {\r
+               size_t len = mxGetNumberOfElements(matlabArray);\r
+               mxChar *buf = mxGetChars(matlabArray);\r
+               jintArray jdims = getMatlabArrayDims(env, matlabArray);\r
+               jcharArray bytes = (*env)->NewCharArray(env, tojsize(len));\r
+               (*env)->SetCharArrayRegion(env, bytes, 0, tojsize(len), buf);\r
+               {\r
+                       jobject result = (*env)->NewObject(env, characterArrayClass, constructor, jdims, bytes);\r
+                       return result;\r
+               }\r
+       }\r
+}\r
+\r
+/**\r
+ * Get the contents of a Matlab struct array as java.util.Map[].\r
+ */\r
+jobject getJavaStructArray(JNIEnv *env, mxArray *matlabArray) {\r
+       jclass structArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/StructArray");\r
+       jmethodID constructor = (*env)->GetMethodID(env, structArrayClass, "<init>", "([ILjava/util/Collection;)V");\r
+       jmethodID setFieldMethod = (*env)->GetMethodID(env, structArrayClass, "setField", "(ILjava/lang/String;Lorg/simantics/matlablink/MatlabArray;)V");\r
+\r
+       jclass arrayListClass = (*env)->FindClass(env, "java/util/ArrayList");\r
+       jmethodID arrayListConstructor = (*env)->GetMethodID(env, arrayListClass, "<init>", "()V");\r
+       jmethodID addMethod = (*env)->GetMethodID(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");\r
+       jmethodID getMethod = (*env)->GetMethodID(env, arrayListClass, "get", "(I)Ljava/lang/Object;");\r
+\r
+       size_t nelems = mxGetNumberOfElements(matlabArray);\r
+       jintArray jdims = getMatlabArrayDims(env, matlabArray);\r
+       size_t len = mxGetNumberOfElements(matlabArray);\r
+       int nFields = mxGetNumberOfFields(matlabArray);\r
+       jsize jlen = tojsize(len);\r
+\r
+       jobject fields = (*env)->NewObject(env, arrayListClass, arrayListConstructor);\r
+\r
+       int j;\r
+\r
+       for (j = 0; j < nFields; j++) {\r
+               jstring fieldName = (*env)->NewStringUTF(env, mxGetFieldNameByNumber(matlabArray, j));\r
+               (*env)->CallVoidMethod(env, fields, addMethod, fieldName);\r
+       }\r
+\r
+       {\r
+               jobject result = (*env)->NewObject(env, structArrayClass, constructor, jdims, fields);\r
+\r
+               for (j = 0; j < nFields; j++) {\r
+                       jstring fieldName = (jstring)(*env)->CallObjectMethod(env, fields, getMethod, j);\r
+                       jint i;\r
+                       for (i = 0; i < jlen; i++) {\r
+                               jobject value = getJavaArray(env, mxGetFieldByNumber(matlabArray, i, j));\r
+                               (*env)->CallVoidMethod(env, result, setFieldMethod, i, fieldName, value);\r
+                       }\r
+               }\r
+\r
+               return result;\r
+       }\r
+}\r
+\r
+/**\r
+ * Get the contents of a Matlab cell array as java.lang.Object[].\r
+ */\r
+jobject getJavaCellArray(JNIEnv *env, mxArray *matlabArray) {\r
+       size_t i;\r
+       jclass cellArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/CellArray");\r
+       jmethodID constructor = (*env)->GetMethodID(env, cellArrayClass, "<init>", "([I)V");\r
+       jmethodID setCellItemMethod = (*env)->GetMethodID(env, cellArrayClass, "setCellItem", "(ILorg/simantics/matlablink/MatlabArray;)V");\r
+\r
+       jintArray jdims = getMatlabArrayDims(env, matlabArray);\r
+       jobject result = (*env)->NewObject(env, cellArrayClass, constructor, jdims);\r
+\r
+       size_t len = mxGetNumberOfElements(matlabArray);\r
+       for (i = 0; i < len; i++) {\r
+               mxArray *item = mxGetCell(matlabArray, i);\r
+               if (item != NULL)\r
+                       (*env)->CallVoidMethod(env, result, setCellItemMethod, (jint)i, getJavaArray(env, item));\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+/**\r
+ * Get the value of a Matlab array as a type-dependent Java object.\r
+ *\r
+ * The currently supported Matlab data types are:\r
+ *  - character\r
+ *  - double\r
+ *  - struct\r
+ *  - cell\r
+ */\r
+jobject getJavaArray(JNIEnv *env, mxArray *item) {\r
+       switch (mxGetClassID(item)) {\r
+       case mxCHAR_CLASS:\r
+               return getJavaCharacterArray(env, item);\r
+               break;\r
+       case mxCELL_CLASS:\r
+               return getJavaCellArray(env, item);\r
+               break;\r
+       case mxSTRUCT_CLASS:\r
+               return getJavaStructArray(env, item);\r
+               break;\r
+       case mxDOUBLE_CLASS:\r
+               return getJavaDoubleArray(env, item);\r
+               break;\r
+       default:\r
+               return NULL;\r
+               break;\r
+       }\r
+}\r
+\r
+JNIEXPORT jlong JNICALL Java_org_simantics_matlablink_Engine_openMatlabEngineImpl(JNIEnv *env, jobject thisObj, jstring workingDirectory) {\r
+       jsize len = (*env)->GetStringUTFLength(env, workingDirectory);\r
+       const char *bytes = (*env)->GetStringUTFChars(env, workingDirectory, NULL);\r
+       char *buf = (char*)malloc(len + 6);\r
+\r
+       // Open Matlab engine\r
+       Engine *engine = engOpen(NULL);\r
+       jlong result = (jlong)engine;\r
+\r
+       // Make Matlab use UTF-8 by default\r
+       engEvalString(engine, UTF8FEATURE);\r
+\r
+       // Switch current directory\r
+       sprintf(buf, "cd('%s')", bytes);\r
+       (*env)->ReleaseStringUTFChars(env, workingDirectory, bytes);\r
+       engEvalString(engine, buf);\r
+\r
+       // Return the engine pointer as a Java long\r
+       return result;\r
+}\r
+\r
+JNIEXPORT void JNICALL Java_org_simantics_matlablink_Engine_closeMatlabEngineImpl(JNIEnv *env, jobject thisObj, jlong engineID) {\r
+       Engine *engine = (Engine *)engineID;\r
+       engClose(engine);\r
+}\r
+\r
+mxArray *getMatlabVariable(JNIEnv *env, Engine *engine, jstring variableName) {\r
+       const char *name = (*env)->GetStringUTFChars(env, variableName, NULL);\r
+       mxArray *result = engGetVariable(engine, name);\r
+       (*env)->ReleaseStringUTFChars(env, variableName, name);\r
+       return result;\r
+}\r
+\r
+int putMatlabVariable(JNIEnv *env, Engine *engine, jstring variableName, mxArray *value) {\r
+       const char *name = (*env)->GetStringUTFChars(env, variableName, NULL);\r
+       int status = engPutVariable(engine, name, value);\r
+       (*env)->ReleaseStringUTFChars(env, variableName, name);\r
+       return status;\r
+}\r
+\r
+mxArray *getMatlabDoubleArray(JNIEnv *env, jobject javaObject) {\r
+       jclass doubleArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/DoubleArray");\r
+       jmethodID getDoubleValueMethod = (*env)->GetMethodID(env, doubleArrayClass, "getDoubleValue", "()[D");\r
+       jmethodID dimsMethod = (*env)->GetMethodID(env, doubleArrayClass, "dims", "()[I");\r
+\r
+       jdoubleArray value = (*env)->CallObjectMethod(env, javaObject, getDoubleValueMethod);\r
+       jintArray jdims = (*env)->CallObjectMethod(env, javaObject, dimsMethod);\r
+\r
+       // Get vector dimentions\r
+       jsize ndims = (*env)->GetArrayLength(env, jdims);\r
+       jsize *jdimArray = (*env)->GetIntArrayElements(env, jdims, NULL);\r
+       size_t *dims = (size_t*)malloc(ndims * sizeof(size_t));\r
+\r
+       jint i;\r
+\r
+       for (i = 0; i < ndims; i++) {\r
+               dims[i] = jdimArray[i];\r
+       }\r
+\r
+       (*env)->ReleaseIntArrayElements(env, jdims, jdimArray, JNI_ABORT);\r
+\r
+       {\r
+               mxArray *result = mxCreateNumericArray(ndims, dims, mxDOUBLE_CLASS, mxREAL);\r
+               jsize len = (*env)->GetArrayLength(env, value);\r
+               double *data = mxGetPr(result);\r
+               double *jdata = (*env)->GetDoubleArrayElements(env, value, NULL);\r
+\r
+               free(dims);\r
+\r
+               // Copy data from Java array\r
+               memcpy(data, jdata, len * sizeof(double));\r
+\r
+               (*env)->ReleaseDoubleArrayElements(env, value, jdata, JNI_ABORT);\r
+\r
+               return result;\r
+       }\r
+}\r
+\r
+mxArray *getMatlabCharacterArray(JNIEnv *env, jobject javaArray) {\r
+       jclass characterArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/CharacterArray");\r
+       jmethodID getCharactersMethod = (*env)->GetMethodID(env, characterArrayClass, "getCharacters", "()[C");\r
+       jmethodID dimsMethod = (*env)->GetMethodID(env, characterArrayClass, "dims", "()[I");\r
+\r
+       jcharArray value = (jcharArray)(*env)->CallObjectMethod(env, javaArray, getCharactersMethod);\r
+       jintArray jdims = (*env)->CallObjectMethod(env, javaArray, dimsMethod);\r
+\r
+       // Get vector dimentions\r
+       jsize ndims = (*env)->GetArrayLength(env, jdims);\r
+       jsize *jdimArray = (*env)->GetIntArrayElements(env, jdims, NULL);\r
+       size_t *dims = (size_t*)malloc(ndims * sizeof(size_t));\r
+\r
+       jint i;\r
+\r
+       for (i = 0; i < ndims; i++) {\r
+               dims[i] = jdimArray[i];\r
+       }\r
+\r
+       {\r
+               mxArray *charArray = mxCreateCharArray(ndims, dims);\r
+\r
+               jsize len = (*env)->GetArrayLength(env, value);\r
+               jchar *bytes = (*env)->GetCharArrayElements(env, value, NULL);\r
+               mxChar *bytesOut = mxGetChars(charArray);\r
+\r
+               free(dims);\r
+               (*env)->ReleaseIntArrayElements(env, jdims, jdimArray, JNI_ABORT);\r
+\r
+               memcpy(bytesOut, bytes, len * sizeof(jchar));\r
+\r
+               (*env)->ReleaseCharArrayElements(env, value, bytes, JNI_ABORT);\r
+\r
+               return charArray;\r
+       }\r
+}\r
+\r
+mxArray *getMatlabStructArray(JNIEnv *env, jobject value) {\r
+       jclass structArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/StructArray");\r
+       jmethodID getFieldMethod = (*env)->GetMethodID(env, structArrayClass, "getField", "(ILjava/lang/String;)Lorg/simantics/matlablink/MatlabArray;");\r
+       jmethodID getFieldsMethod = (*env)->GetMethodID(env, structArrayClass, "getFields", "()[Ljava/lang/String;");\r
+       jmethodID dimsMethod = (*env)->GetMethodID(env, structArrayClass, "dims", "()[I");\r
+\r
+       jobjectArray fields = (*env)->CallObjectMethod(env, value, getFieldsMethod);\r
+\r
+       jint i, nfields = (*env)->GetArrayLength(env, fields);\r
+       char **fieldNames = (char**)malloc(nfields * sizeof(char*));\r
+\r
+       for (i = 0; i < nfields; i++) {\r
+               jstring field = (jstring)(*env)->GetObjectArrayElement(env, fields, i);\r
+               const char *chars = (*env)->GetStringUTFChars(env, field, NULL);\r
+               fieldNames[i] = strdup(chars);\r
+               (*env)->ReleaseStringUTFChars(env, field, chars);\r
+       }\r
+\r
+       {\r
+               // Get vector dimentions\r
+               jintArray jdims = (*env)->CallObjectMethod(env, value, dimsMethod);\r
+               jsize ndims = (*env)->GetArrayLength(env, jdims);\r
+               jsize *jdimArray = (*env)->GetIntArrayElements(env, jdims, NULL);\r
+               size_t *dims = (size_t*)malloc(ndims * sizeof(size_t));\r
+               mxArray *result;\r
+               jsize len = ndims > 0 ? 1 : 0;\r
+\r
+               for (i = 0; i < ndims; i++) {\r
+                       dims[i] = jdimArray[i];\r
+                       len = len * jdimArray[i];\r
+               }\r
+\r
+               result = mxCreateStructArray(ndims, dims, nfields, fieldNames);\r
+\r
+               free(dims);\r
+\r
+               for (i = 0; i < nfields; i++) {\r
+                       jstring field = (jstring)(*env)->GetObjectArrayElement(env, fields, i);\r
+                       int j;\r
+\r
+                       for (j = 0; j < len; j++) {\r
+                               jobject item = (*env)->CallObjectMethod(env, value, getFieldMethod, (jint)j, field);\r
+                               mxSetFieldByNumber(result, j, i, getMatlabArray(env, item));\r
+                       }\r
+               }\r
+\r
+               for (i = 0; i < nfields; i++)\r
+                       if (fieldNames[i] != NULL) free(fieldNames[i]);\r
+\r
+               free(fieldNames);\r
+\r
+               return result;\r
+       }\r
+}\r
+\r
+mxArray *getMatlabCellArray(JNIEnv *env, jobject value) {\r
+       jclass cellArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/CellArray");\r
+       jmethodID getCellValueMethod = (*env)->GetMethodID(env, cellArrayClass, "getCellValue", "()[Lorg/simantics/matlablink/MatlabArray;");\r
+       jmethodID dimsMethod = (*env)->GetMethodID(env, cellArrayClass, "dims", "()[I");\r
+\r
+       jobjectArray values = (*env)->CallObjectMethod(env, value, getCellValueMethod);\r
+       jintArray jdims = (*env)->CallObjectMethod(env, value, dimsMethod);\r
+\r
+       // Get vector dimentions\r
+       jsize len = (*env)->GetArrayLength(env, values);\r
+       jsize ndims = (*env)->GetArrayLength(env, jdims);\r
+       jsize *jdimArray = (*env)->GetIntArrayElements(env, jdims, NULL);\r
+       size_t *dims = (size_t*)malloc(ndims * sizeof(size_t));\r
+\r
+       jint i;\r
+\r
+       for (i = 0; i < ndims; i++) {\r
+               dims[i] = jdimArray[i];\r
+       }\r
+\r
+       {\r
+               // Create temporary Matlab array\r
+               mxArray *matlabValue = mxCreateCellArray(ndims, dims);\r
+\r
+               // Copy data from Java array\r
+               for (i = 0; i < len; i++) {\r
+                       jobject item = (*env)->GetObjectArrayElement(env, values, i);\r
+                       mxArray *matlabItem = getMatlabArray(env, item);\r
+                       if (matlabItem != NULL) {\r
+                               mxSetCell(matlabValue, i, matlabItem);\r
+                       }\r
+               }\r
+\r
+               return matlabValue;\r
+       }\r
+}\r
+\r
+mxArray *getMatlabArray(JNIEnv *env, jobject item) {\r
+       jclass doubleArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/DoubleArray");\r
+       jclass characterArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/CharacterArray");\r
+       jclass cellArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/CellArray");\r
+       jclass structArrayClass = (*env)->FindClass(env, "org/simantics/matlablink/StructArray");\r
+\r
+       mxArray *matlabItem = NULL;\r
+       if ((*env)->IsInstanceOf(env, item, doubleArrayClass)) {\r
+               matlabItem = getMatlabDoubleArray(env, item);\r
+       }\r
+       else if ((*env)->IsInstanceOf(env, item, characterArrayClass)) {\r
+               matlabItem = getMatlabCharacterArray(env, item);\r
+       }\r
+       else if ((*env)->IsInstanceOf(env, item, cellArrayClass)) {\r
+               matlabItem = getMatlabCellArray(env, item);\r
+       }\r
+       else if ((*env)->IsInstanceOf(env, item, structArrayClass)) {\r
+               matlabItem = getMatlabStructArray(env, item);\r
+       }\r
+\r
+       return matlabItem;\r
+}\r
+\r
+// Generic arrays\r
+JNIEXPORT jobject JNICALL Java_org_simantics_matlablink_Engine_getMatlabArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring varName) {\r
+       Engine *engine = (Engine *)engineID;\r
+\r
+       if (varName == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable name given");\r
+       }\r
+\r
+       {\r
+               mxArray *array = getMatlabVariable(env, engine, varName);\r
+\r
+               if (array == NULL) {\r
+                       throwException(env, "java/lang/RuntimeException", "Variable not found");\r
+                       return NULL;\r
+               }\r
+\r
+               {\r
+                       jobject result = getJavaArray(env, array);\r
+\r
+                       mxDestroyArray(array);\r
+\r
+                       if (result == NULL) {\r
+                               throwException(env, "java/lang/RuntimeException", "Matlab variable type not supported");\r
+                               return NULL;\r
+                       }\r
+\r
+                       return result;\r
+               }\r
+       }\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_matlablink_Engine_setMatlabArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring variableName, jobject value) {\r
+       if (variableName == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable name given");\r
+               return 0;\r
+       }\r
+\r
+       if (value == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable value given");\r
+               return 0;\r
+       }\r
+\r
+       {\r
+               Engine *engine = (Engine *)engineID;\r
+\r
+               // Get value as mxArray\r
+               mxArray *matlabValue = getMatlabArray(env, value);\r
+\r
+               if (matlabValue == NULL) {\r
+                       throwException(env, "java/lang/RuntimeException", "Input not a suitable value for a Matlab array");\r
+                       return 0;\r
+               }\r
+\r
+               {\r
+                       // Set variable value\r
+                       int status = putMatlabVariable(env, engine, variableName, matlabValue);\r
+\r
+                       // Destroy array object\r
+                       mxDestroyArray(matlabValue);\r
+\r
+                       return status;\r
+               }\r
+       }\r
+}\r
+\r
+// Double arrays\r
+JNIEXPORT jobject JNICALL Java_org_simantics_matlablink_Engine_getMatlabDoubleArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring varName) {\r
+       Engine *engine = (Engine *)engineID;\r
+\r
+       if (varName == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable name given");\r
+       }\r
+\r
+       {\r
+               mxArray *array = getMatlabVariable(env, engine, varName);\r
+\r
+               if (array == NULL) {\r
+                       throwException(env, "java/lang/RuntimeException", "Variable not found");\r
+                       return NULL;\r
+               }\r
+\r
+               if (!mxIsDouble(array)) {\r
+                       throwException(env, "java/lang/RuntimeException", "Variable not a double array");\r
+                       return NULL;\r
+               }\r
+\r
+               {\r
+                       jdoubleArray result = getJavaDoubleArray(env, array);\r
+                       mxDestroyArray(array);\r
+                       return result;\r
+               }\r
+       }\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_matlablink_Engine_setMatlabDoubleArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring variableName, jobject value) {\r
+       if (variableName == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable name given");\r
+               return 0;\r
+       }\r
+\r
+       if (value == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable value given");\r
+               return 0;\r
+       }\r
+\r
+       {\r
+               Engine *engine = (Engine *)engineID;\r
+\r
+               // Get value as mxArray\r
+               mxArray *matlabValue = getMatlabDoubleArray(env, value);\r
+\r
+               // Set variable value\r
+               int status = putMatlabVariable(env, engine, variableName, matlabValue);\r
+\r
+               // Destroy array object\r
+               mxDestroyArray(matlabValue);\r
+\r
+               return status;\r
+       }\r
+}\r
+\r
+// Cell arrays\r
+JNIEXPORT jobject JNICALL Java_org_simantics_matlablink_Engine_getMatlabCellArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring varName) {\r
+       Engine *engine = (Engine *)engineID;\r
+\r
+       if (varName == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable name given");\r
+               return NULL;\r
+       }\r
+\r
+       {\r
+               // Get variable value from Matlab\r
+               mxArray *array = getMatlabVariable(env, engine, varName);\r
+\r
+               if (array == NULL) {\r
+                       throwException(env, "java/lang/RuntimeException", "Variable not found");\r
+                       return NULL;\r
+               }\r
+\r
+               if (!mxIsCell(array)) {\r
+                       throwException(env, "java/lang/RuntimeException", "Variable not a cell array");\r
+                       return NULL;\r
+               }\r
+\r
+               {\r
+                       jobject result = getJavaCellArray(env, array);\r
+                       mxDestroyArray(array);\r
+\r
+                       if (result == NULL) {\r
+                               throwException(env, "java/lang/RuntimeException", "Matlab variable type not supported");\r
+                               return NULL;\r
+                       }\r
+\r
+                       return result;\r
+               }\r
+       }\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_matlablink_Engine_setMatlabCellArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring variableName, jobject value) {\r
+       if (variableName == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable name given");\r
+               return 0;\r
+       }\r
+\r
+       if (value == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable value given");\r
+               return 0;\r
+       }\r
+\r
+       {\r
+               Engine *engine = (Engine *)engineID;\r
+\r
+               // Get value as mxArray\r
+               mxArray *matlabValue = getMatlabCellArray(env, value);\r
+\r
+               // Set variable value\r
+               int status = putMatlabVariable(env, engine, variableName, matlabValue);\r
+\r
+               // Destroy array object\r
+               mxDestroyArray(matlabValue);\r
+\r
+               return status;\r
+       }\r
+}\r
+\r
+// Character arrays\r
+JNIEXPORT jobject JNICALL Java_org_simantics_matlablink_Engine_getMatlabCharacterArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring varName) {\r
+       Engine *engine = (Engine *)engineID;\r
+\r
+       if (varName == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable name given");\r
+               return NULL;\r
+       }\r
+\r
+       {\r
+               // Get variable value from Matlab\r
+               mxArray *array = getMatlabVariable(env, engine, varName);\r
+\r
+               if (array == NULL) {\r
+                       throwException(env, "java/lang/RuntimeException", "Variable not found");\r
+                       return NULL;\r
+               }\r
+\r
+               if (!mxIsChar(array)) {\r
+                       throwException(env, "java/lang/RuntimeException", "Variable not a character array");\r
+                       return NULL;\r
+               }\r
+\r
+               {\r
+                       jobject result = getJavaCharacterArray(env, array);\r
+                       mxDestroyArray(array);\r
+\r
+                       if (result == NULL) {\r
+                               throwException(env, "java/lang/RuntimeException", "Matlab variable type not supported");\r
+                               return NULL;\r
+                       }\r
+\r
+                       return result;\r
+               }\r
+       }\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_matlablink_Engine_setMatlabCharacterArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring variableName, jobject value) {\r
+       if (variableName == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable name given");\r
+               return 0;\r
+       }\r
+\r
+       if (value == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable value given");\r
+               return 0;\r
+       }\r
+\r
+       {\r
+               Engine *engine = (Engine *)engineID;\r
+\r
+               // Get value as mxArray\r
+               mxArray *matlabValue = getMatlabCharacterArray(env, value);\r
+\r
+               // Set variable value\r
+               int status = putMatlabVariable(env, engine, variableName, matlabValue);\r
+\r
+               // Destroy array object\r
+               mxDestroyArray(matlabValue);\r
+\r
+               return status;\r
+       }\r
+}\r
+\r
+// Struct arrays\r
+JNIEXPORT jobject JNICALL Java_org_simantics_matlablink_Engine_getMatlabStructArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring varName) {\r
+       Engine *engine = (Engine *)engineID;\r
+\r
+       if (varName == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable name given");\r
+               return NULL;\r
+       }\r
+\r
+       {\r
+               // Get variable value from Matlab\r
+               mxArray *array = getMatlabVariable(env, engine, varName);\r
+\r
+               if (array == NULL) {\r
+                       throwException(env, "java/lang/RuntimeException", "Variable not found");\r
+                       return NULL;\r
+               }\r
+\r
+               if (!mxIsStruct(array)) {\r
+                       throwException(env, "java/lang/RuntimeException", "Variable not a struct array");\r
+                       return NULL;\r
+               }\r
+\r
+               {\r
+                       jobject result = getJavaStructArray(env, array);\r
+                       mxDestroyArray(array);\r
+\r
+                       if (result == NULL) {\r
+                               throwException(env, "java/lang/RuntimeException", "Matlab variable type not supported");\r
+                               return NULL;\r
+                       }\r
+\r
+                       return result;\r
+               }\r
+       }\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_matlablink_Engine_setMatlabStructArrayImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring variableName, jobject value) {\r
+       if (variableName == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable name given");\r
+               return 0;\r
+       }\r
+\r
+       if (value == NULL) {\r
+               throwIllegalArgumentException(env, "Null variable value given");\r
+               return 0;\r
+       }\r
+\r
+       {\r
+               Engine *engine = (Engine *)engineID;\r
+\r
+               // Get value as mxArray\r
+               mxArray *matlabValue = getMatlabStructArray(env, value);\r
+\r
+               // Set variable value\r
+               int status = putMatlabVariable(env, engine, variableName, matlabValue);\r
+\r
+               // Destroy array object\r
+               mxDestroyArray(matlabValue);\r
+\r
+               return status;\r
+       }\r
+}\r
+\r
+// Expression evaluation\r
+JNIEXPORT jint JNICALL Java_org_simantics_matlablink_Engine_evaluateMatlabExpressionImpl(JNIEnv *env, jobject thisObj, jlong engineID, jstring expression) {\r
+       Engine *engine = (Engine *)engineID;\r
+       const char *expr = (*env)->GetStringUTFChars(env, expression, NULL);\r
+\r
+       int status = engEvalString(engine, expr);\r
+\r
+       (*env)->ReleaseStringUTFChars(env, expression, expr);\r
+\r
+       return status;\r
+}\r
+\r
+//extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)\r
+BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)\r
+{\r
+    switch (fdwReason)\r
+    {\r
+        case DLL_PROCESS_ATTACH:\r
+            // attach to process\r
+            break;\r
+\r
+        case DLL_PROCESS_DETACH:\r
+            // detach from process\r
+            break;\r
+\r
+        case DLL_THREAD_ATTACH:\r
+            // attach to thread\r
+            break;\r
+\r
+        case DLL_THREAD_DETACH:\r
+            // detach from thread\r
+            break;\r
+    }\r
+    return TRUE; // succesful\r
+}\r
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 (file)
index 0000000..e432609
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef __SCLMAT_H__\r
+#define __SCLMAT_H__\r
+\r
+#include <windows.h>\r
+\r
+/*  To use this exported function of dll, include this header\r
+ *  in your project.\r
+ */\r
+\r
+#ifdef BUILD_DLL\r
+    #define DLL_EXPORT __declspec(dllexport)\r
+#else\r
+    #define DLL_EXPORT __declspec(dllimport)\r
+#endif\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+__declspec (dllexport) void __stdcall start(char*, double*, int, int);\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif // __SCLMAT_H__\r
diff --git a/org.simantics.matlablink/.classpath b/org.simantics.matlablink/.classpath
new file mode 100644 (file)
index 0000000..069739a
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
+       <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="src" path="test"/>\r
+       <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
diff --git a/org.simantics.matlablink/.gitignore b/org.simantics.matlablink/.gitignore
new file mode 100644 (file)
index 0000000..ae3c172
--- /dev/null
@@ -0,0 +1 @@
+/bin/
diff --git a/org.simantics.matlablink/.project b/org.simantics.matlablink/.project
new file mode 100644 (file)
index 0000000..f8aba66
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>org.simantics.matlablink</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.ManifestBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.pde.SchemaBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>org.eclipse.pde.PluginNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
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 (file)
index 0000000..e6babf3
--- /dev/null
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1\r
+encoding//test/org/simantics/matlablink/test/TestMatlabEngine.java=UTF-8\r
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 (file)
index 0000000..295926d
--- /dev/null
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1\r
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled\r
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8\r
+org.eclipse.jdt.core.compiler.compliance=1.8\r
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error\r
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error\r
+org.eclipse.jdt.core.compiler.source=1.8\r
diff --git a/org.simantics.matlablink/META-INF/MANIFEST.MF b/org.simantics.matlablink/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..d013e1c
--- /dev/null
@@ -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 (file)
index 0000000..840ba6a
--- /dev/null
@@ -0,0 +1,6 @@
+source.. = src/\r
+output.. = bin/\r
+bin.includes = META-INF/,\\r
+               .,\\r
+               scl/\r
+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 (file)
index 0000000..811e0aa
--- /dev/null
@@ -0,0 +1,97 @@
+import "Map" as Map\r
+import "Vector"\r
+import "File"\r
+\r
+effect Matlab\r
+    "Simantics/Matlab/Matlab"\r
+    "org.simantics.matlablink.Engine"\r
+\r
+importJava "org.simantics.matlablink.MatlabArray"\r
+    data MatlabArray\r
+importJava "org.simantics.matlablink.DoubleArray"\r
+    data DoubleArray\r
+importJava "org.simantics.matlablink.CharacterArray"\r
+    data CharacterArray\r
+importJava "org.simantics.matlablink.CellArray"\r
+    data CellArray\r
+importJava "org.simantics.matlablink.StructArray"\r
+    data StructArray\r
+\r
+importJava "org.simantics.matlablink.Engine" where\r
+    data Engine\r
+\r
+    @JavaName close\r
+    closeEngine :: Engine -> <Proc> ()\r
+    \r
+    @JavaName evaluateMatlabExpression \r
+    executeMatlabExpression :: String -> <Matlab, Proc> ()\r
+    \r
+    getMatlabArray :: String -> <Matlab, Proc> MatlabArray\r
+    getMatlabDoubleArray :: String -> <Matlab, Proc> DoubleArray\r
+    getMatlabCharacterArray :: String -> <Matlab, Proc> ChracterArray\r
+    getMatlabCellArray :: String -> <Matlab, Proc> CellArray\r
+    getMatlabStructArray :: String -> <Matlab, Proc> StructArray\r
+    \r
+    setMatlabArray :: String -> MatlabArray -> <Matlab, Proc> ()\r
+    setMatlabDoubleArray :: String -> DoubleArray -> <Matlab, Proc> ()\r
+    setMatlabCharacterArray :: String -> CharacterArray -> <Matlab, Proc> ()\r
+    setMatlabCellArray :: String -> CellArray -> <Matlab, Proc> ()\r
+    setMatlabStructArray :: String -> StructArray -> <Matlab, Proc> ()\r
+\r
+importJava "org.simantics.matlablink.Matlab" where\r
+    @JavaName runWithEngine\r
+    runWithEngineF :: Engine -> (() -> <Matlab, Proc> a) -> <Proc> a\r
+    \r
+    @JavaName runMatlab\r
+    runMatlabF :: File -> (() -> <Matlab, Proc> a) -> <Proc> a\r
+    \r
+    matchMatlabArray :: a -> (Vector Double -> b) -> (String -> b) -> (Vector Dynamic -> b) -> (Map.T String (Vector Dynamic) -> b) -> b\r
+    \r
+    openEngine :: File -> <Proc> Engine\r
+\r
+runWithEngine :: Engine -> <Matlab, Proc> a -> <Proc> a\r
+runWithEngine engine v = runWithEngineF engine (\_ -> v)\r
+\r
+runMatlab :: File -> <Matlab, Proc> a -> <Proc> a\r
+runMatlab wd v = runMatlabF wd (\_ -> v)\r
+\r
+evaluateMatlabExpression :: MatlabCompatible a => String -> <Matlab, Proc> a\r
+evaluateMatlabExpression expression = do\r
+    executeMatlabExpression expression\r
+    getMatlabVariable "ans"\r
+\r
+class (Typeable a) => MatlabCompatible a where\r
+    getMatlabVariable :: String -> <Matlab, Proc> a\r
+    setMatlabVariable :: String -> a -> <Matlab, Proc> ()\r
+\r
+instance MatlabCompatible (Vector Double) where\r
+    getMatlabVariable = getMatlabDoubleArray\r
+    setMatlabVariable name value = setMatlabDoubleArray name False value\r
+\r
+instance MatlabCompatible [Double] where\r
+    getMatlabVariable = vectorToList . getMatlabDoubleArray\r
+    setMatlabVariable name value = setMatlabDoubleArray name False (vector value)\r
+\r
+instance MatlabCompatible Double where\r
+    getMatlabVariable name = (getMatlabDoubleArray name)!0\r
+    setMatlabVariable name value = setMatlabDoubleArray name False (vector [value])\r
+    \r
+instance MatlabCompatible String where\r
+    getMatlabVariable = getMatlabCharacterArray\r
+    setMatlabVariable = setMatlabCharacterArray\r
+    \r
+instance MatlabCompatible (Vector Dynamic) where\r
+    getMatlabVariable = getMatlabCellArray\r
+    setMatlabVariable name value = setMatlabCellArray name False value\r
+\r
+instance MatlabCompatible Dynamic where\r
+    getMatlabVariable = getMatlabArray\r
+    setMatlabVariable = setMatlabArray    \r
+\r
+instance MatlabCompatible (Dynamic, Dynamic) where\r
+    getMatlabVariable name = let\r
+        v = getMatlabCellArray name\r
+      in\r
+        (v!0, v!1)\r
+        \r
+    setMatlabVariable name (a, b) = setMatlabCellArray name False (vector [toDynamic a, toDynamic b])\r
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 (file)
index 0000000..641bd89
--- /dev/null
@@ -0,0 +1,31 @@
+package org.simantics.matlablink;\r
+\r
+import org.osgi.framework.BundleActivator;\r
+import org.osgi.framework.BundleContext;\r
+\r
+public class Activator implements BundleActivator {\r
+\r
+       private static BundleContext context;\r
+\r
+       static BundleContext getContext() {\r
+               return context;\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)\r
+        */\r
+       public void start(BundleContext bundleContext) throws Exception {\r
+               Activator.context = bundleContext;\r
+        System.loadLibrary("jnimatlab");\r
+       }\r
+\r
+       /*\r
+        * (non-Javadoc)\r
+        * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)\r
+        */\r
+       public void stop(BundleContext bundleContext) throws Exception {\r
+               Activator.context = null;\r
+       }\r
+\r
+}\r
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 (file)
index 0000000..253ac04
--- /dev/null
@@ -0,0 +1,92 @@
+package org.simantics.matlablink;\r
+\r
+import java.util.Arrays;\r
+\r
+public class CellArray extends MatlabArray {\r
+    MatlabArray[] value;\r
+    int[] dims;\r
+    \r
+    public CellArray(int length) {\r
+        value = new MatlabArray[length];\r
+        dims = new int[] {1, length};\r
+    }\r
+    \r
+    public CellArray(int... dims) {\r
+        int nelem = 1;\r
+        for (int n : dims) nelem *= n;\r
+        \r
+        this.dims = dims;\r
+        value = new MatlabArray[nelem];\r
+    }\r
+    \r
+    @Override\r
+    public int size() {\r
+        return value.length;\r
+    }\r
+    \r
+    @Override\r
+    public int[] dims() {\r
+        return dims;\r
+    }\r
+    \r
+    public void setCellItem(int index, MatlabArray v) {\r
+        value[index] = v;\r
+    }\r
+    \r
+    @Override\r
+    public boolean isCell() {\r
+        return true;\r
+    }\r
+    \r
+    @Override\r
+    public MatlabArray[] getCellValue() {\r
+        return value;\r
+    }\r
+    \r
+    public MatlabArray getCellItem(int index) {\r
+        return value[index];\r
+    }\r
+    \r
+    public MatlabArray getCellItem(int i, int j) {\r
+        return value[i + dims[0] * j];\r
+    }\r
+    \r
+    public MatlabArray getCellItem(int... k) {\r
+        if (k.length > dims.length) throw new IllegalArgumentException("Too many indexes for array of dimension " + dims.length);\r
+        \r
+        int s = 1;\r
+        int index = 0;\r
+        for (int l = 0; l < k.length; l++) {\r
+            index = index + s * k[l];\r
+            s *= dims[l];\r
+        }\r
+        \r
+        return value[index];\r
+    }\r
+    \r
+    @Override\r
+    public boolean equals( Object obj ) {\r
+        return obj instanceof CellArray &&\r
+               Arrays.equals(this.dims, ((CellArray)obj).dims) &&\r
+               Arrays.equals(this.value, ((CellArray)obj).value);\r
+    }\r
+    \r
+    @Override\r
+    public String toString() {\r
+        StringBuilder sb = new StringBuilder();\r
+        sb.append("{");\r
+        for (int i = 0; i < Math.min(size(), 10); i++) {\r
+            if (i > 0) sb.append(", ");\r
+            sb.append(value[i]);\r
+        }\r
+        if (size() > 10) sb.append(", ...");\r
+        sb.append(" (");\r
+        for (int i = 0; i < dims.length; i++) {\r
+            if (i > 0) sb.append("x");\r
+            sb.append(dims[i]);\r
+        }\r
+        sb.append(")}");\r
+        \r
+        return sb.toString();\r
+    }\r
+}\r
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 (file)
index 0000000..30995e6
--- /dev/null
@@ -0,0 +1,98 @@
+package org.simantics.matlablink;\r
+\r
+import java.util.Arrays;\r
+\r
+public class CharacterArray extends MatlabArray {\r
+    char[] value; // Content as UTF-16 bytes\r
+    int[] dims;\r
+    \r
+    public CharacterArray(char[] value) {\r
+        this.value = value;\r
+        dims = new int[] { 1, value.length };\r
+    }\r
+    \r
+    public CharacterArray(String stringValue) {\r
+        this.value = stringValue.toCharArray();\r
+        dims = new int[] { 1, value.length };\r
+    }\r
+\r
+    public CharacterArray(int dims[], char[] value) {\r
+        int nelem = 1;\r
+        for (int n : dims) nelem *= n;\r
+        \r
+        if (nelem != value.length)\r
+            throw new IllegalArgumentException("Array dimension and value mismatch");\r
+        \r
+        this.value = value;\r
+        this.dims = dims;\r
+    }\r
+    \r
+    @Override\r
+    public int size() {\r
+        return value.length;\r
+    }\r
+    \r
+    @Override\r
+    public int[] dims() {\r
+        return dims;\r
+    }\r
+    \r
+    @Override\r
+    public boolean isCharacter() {\r
+        return true;\r
+    }\r
+    \r
+    @Override\r
+    public String getStringValue() {\r
+        return new String(value);\r
+    }\r
+    \r
+    public char[] getCharacters() {\r
+        return value;\r
+    }\r
+    \r
+    public char getCharacter(int index) {\r
+        return value[index];\r
+    }\r
+    \r
+    public char getCharacter(int... is) {\r
+        if (is.length > dims.length) throw new IllegalArgumentException("Too many indexes for array of dimension " + dims.length);\r
+        \r
+        int index = 0;\r
+        int s = 1;\r
+        for (int k = 0; k < is.length; k++) {\r
+            index = index + s * is[k];\r
+            s *= dims[k];\r
+        }\r
+        \r
+        return value[index];\r
+    }\r
+    \r
+    @Override\r
+    public boolean equals( Object obj ) {\r
+        return obj instanceof CharacterArray &&\r
+               Arrays.equals(this.dims, ((CharacterArray)obj).dims) &&\r
+               Arrays.equals(this.value, ((CharacterArray)obj).value);\r
+    }\r
+    \r
+    @Override\r
+    public String toString() {\r
+        StringBuilder sb = new StringBuilder();\r
+        sb.append("\"");\r
+\r
+        for (int i = 0; i < Math.min(value.length, 160); i++) {\r
+            sb.append(value[i]);\r
+        }\r
+        if (value.length > 160)\r
+            sb.append("...");\r
+        \r
+        sb.append("\"(");\r
+        for (int i = 0; i < dims.length; i++) {\r
+            if (i > 0) sb.append("x");\r
+            sb.append(dims[i]);\r
+        }\r
+        sb.append(")");\r
+        \r
+        return sb.toString();        \r
+    }\r
+}\r
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 (file)
index 0000000..b1fb893
--- /dev/null
@@ -0,0 +1,100 @@
+package org.simantics.matlablink;\r
+\r
+import java.util.Arrays;\r
+\r
+public class DoubleArray extends MatlabArray {\r
+    double[] value;\r
+    int[] dims;\r
+    \r
+    public DoubleArray(double[] value) {\r
+        this.value = value;\r
+        dims = new int[] { 1, value.length };\r
+    }\r
+    \r
+    public DoubleArray(int m, int n, double[] value) {\r
+        if (m * n != value.length)\r
+            throw new IllegalArgumentException("Array dimension and value mismatch");\r
+        \r
+        this.value = value;\r
+        this.dims = new int[] { m, n };\r
+    }\r
+\r
+    public DoubleArray(int[] dims, double[] value) {\r
+        int nelem = dims.length > 0 ? 1 : 0;\r
+        for (int n : dims) nelem *= n;\r
+        \r
+        if (nelem != value.length)\r
+            throw new IllegalArgumentException("Array dimension and value mismatch");\r
+        \r
+        this.value = value;\r
+        this.dims = dims;\r
+    }\r
+    \r
+    @Override\r
+    public boolean isDouble() {\r
+        return true;\r
+    }\r
+    \r
+    @Override\r
+    public int size() {\r
+        return value.length;\r
+    }\r
+    \r
+    @Override\r
+    public int[] dims() {\r
+        return dims;\r
+    }\r
+    \r
+    @Override\r
+    public double[] getDoubleValue() {\r
+        return value;\r
+    }\r
+    \r
+    @Override\r
+    public double getDoubleValue(int index) {\r
+        return value[index];\r
+    }\r
+    \r
+    public double getDoubleValue(int i, int j) {\r
+        return value[i + dims[0] * j];\r
+    }\r
+    \r
+    public double getDoubleValue(int... k) {\r
+        if (k.length > dims.length) throw new IllegalArgumentException("Too many indexes for array of dimension " + dims.length);\r
+        \r
+        int s = 1;\r
+        int index = 0;\r
+        for (int l = 0; l < k.length; l++) {\r
+            index = index + s * k[l];\r
+            s *= dims[l];\r
+        }\r
+        \r
+        return value[index];\r
+    }\r
+    \r
+    @Override\r
+    public boolean equals( Object obj ) {\r
+        return obj instanceof DoubleArray &&\r
+               Arrays.equals(this.dims, ((DoubleArray)obj).dims) &&\r
+               Arrays.equals(this.value, ((DoubleArray)obj).value);\r
+    }\r
+    \r
+    @Override\r
+    public String toString() {\r
+        StringBuilder sb = new StringBuilder();\r
+        sb.append("[");\r
+        for (int i = 0; i < Math.min(size(), 10); i++) {\r
+            if (i > 0) sb.append(", ");\r
+            sb.append(value[i]);\r
+        }\r
+        if (size() > 10) sb.append(", ...");\r
+        sb.append(" (");\r
+        for (int i = 0; i < dims.length; i++) {\r
+            if (i > 0) sb.append("x");\r
+            sb.append(dims[i]);\r
+        }\r
+        sb.append(")]");\r
+        \r
+        return sb.toString();\r
+    }\r
+}\r
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 (file)
index 0000000..eb921fc
--- /dev/null
@@ -0,0 +1,246 @@
+package org.simantics.matlablink;\r
+\r
+import java.io.Closeable;\r
+import java.io.IOException;\r
+\r
+public class Engine implements Closeable {\r
+    private long engineId;\r
+    \r
+    static {\r
+        try {\r
+            System.loadLibrary("jnimatlab"); \r
+        } catch(java.lang.UnsatisfiedLinkError e) {\r
+            System.out.println( "Error loading jnimatlab.dll: " + e.getMessage() );\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Not public, use Matlab.openEngine()\r
+     */\r
+    Engine(String workingDirectory) {\r
+        engineId = openMatlabEngineImpl(workingDirectory);\r
+    }\r
+    \r
+    /**\r
+     * Is the Matlab Engine connection open?\r
+     */\r
+    public boolean isOpen() {\r
+        return engineId != 0;\r
+    }\r
+    \r
+    /**\r
+     * Close the Matlab Engine connection\r
+     */\r
+    @Override\r
+    public void close() throws IOException {\r
+        long id = engineId;\r
+        engineId = 0;\r
+        closeMatlabEngineImpl(id);\r
+    }\r
+\r
+    /**\r
+     * Get the value of a Matlab variable.\r
+     * \r
+     * The return type depends on the type of the Matlab variable, and\r
+     * matches the return type of the corresponding type-specific access\r
+     * function.\r
+     */\r
+    public MatlabArray getMatlabArray(String variableName) {\r
+        if (variableName == null || variableName.isEmpty())\r
+            throw new IllegalArgumentException("Invalid Matlab variable name \'" + variableName + "\'");\r
+        \r
+        MatlabArray result;\r
+        synchronized ( this ) {\r
+            result = getMatlabArrayImpl(engineId, variableName);\r
+        }\r
+        \r
+        return result;\r
+    }\r
+    \r
+    /**\r
+     * Set the value of a Matlab variable.\r
+     * \r
+     * The value must be of a Java type that is supported by one of the type-specific\r
+     * access functions. An exception is thrown, if the value is not of a recognized type.\r
+     */\r
+    public void setMatlabArray(String variableName, MatlabArray value) {\r
+        if (value == null)\r
+            throw new IllegalArgumentException("Invalid Matlab array value given");       \r
+        \r
+        int result;\r
+        synchronized ( this ) {\r
+            result = setMatlabArrayImpl(engineId, variableName, value);\r
+        }\r
+        \r
+        if (result != 0) {\r
+            throw new RuntimeException("Setting Matlab variable value failed");\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Get the value of a Matlab double array variable.\r
+     */\r
+    public DoubleArray getMatlabDoubleArray(String variableName) {\r
+        if (variableName == null || variableName.isEmpty())\r
+            throw new IllegalArgumentException("Invalid Matlab variable name \'" + variableName + "\'");\r
+        \r
+        DoubleArray result;\r
+        synchronized ( this ) {\r
+            result = getMatlabDoubleArrayImpl(engineId, variableName);\r
+        }\r
+        \r
+        return result;\r
+    }\r
+    \r
+    /**\r
+     * Set the value of a Matlab variable to a double array.\r
+     */\r
+    public void setMatlabDoubleArray(String variableName, DoubleArray value) {\r
+        if (value == null)\r
+            throw new IllegalArgumentException("Invalid Matlab array value given");       \r
+        \r
+        int result;\r
+        synchronized ( this ) {\r
+            result = setMatlabDoubleArrayImpl(engineId, variableName, value);\r
+        }\r
+        \r
+        if (result != 0) {\r
+            throw new RuntimeException("Setting Matlab variable value failed");\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Get the value of a Matlab cell array variable.\r
+     */   \r
+    public CellArray getMatlabCellArray(String variableName) {\r
+        if (variableName == null || variableName.isEmpty())\r
+            throw new IllegalArgumentException("Invalid Matlab variable name \'" + variableName + "\'");\r
+        \r
+        CellArray result;\r
+        synchronized ( this ) {\r
+            result = getMatlabCellArrayImpl(engineId, variableName);\r
+        }\r
+        \r
+        return result;\r
+    }\r
+    \r
+    /**\r
+     * Set the value of a Matlab variable to a cell array.\r
+     */\r
+    public void setMatlabCellArray(String variableName, CellArray value) {\r
+        if (value == null)\r
+            throw new IllegalArgumentException("Invalid Matlab array value given");\r
+        \r
+        int result;\r
+        synchronized ( this ) {\r
+            result = setMatlabCellArrayImpl(engineId, variableName, value);\r
+        }\r
+        \r
+        if (result != 0) {\r
+            throw new RuntimeException("Setting Matlab variable value failed");\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Get the value of a Matlab character array variable.\r
+     */   \r
+    public CharacterArray getMatlabCharacterArray(String variableName) {\r
+        if (variableName == null || variableName.isEmpty())\r
+            throw new IllegalArgumentException("Invalid Matlab variable name \'" + variableName + "\'");\r
+        \r
+        CharacterArray result;\r
+        synchronized ( this ) {\r
+            result = getMatlabCharacterArrayImpl(engineId, variableName);\r
+        }\r
+        \r
+        return result;\r
+    }\r
+    \r
+    /**\r
+     * Set the value of a Matlab variable to a character array.\r
+     */\r
+    public void setMatlabCharacterArray(String variableName, CharacterArray value) {\r
+        if (value == null)\r
+            throw new IllegalArgumentException("Invalid Matlab array value given");\r
+        \r
+        int result;\r
+        synchronized ( this ) {\r
+            result = setMatlabCharacterArrayImpl(engineId, variableName, value);\r
+        }\r
+        \r
+        if (result != 0) {\r
+            throw new RuntimeException("Setting Matlab variable value failed");\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Get the value of a Matlab struct array variable.\r
+     */   \r
+    public StructArray getMatlabStructArray(String variableName) {\r
+        if (variableName == null || variableName.isEmpty())\r
+            throw new IllegalArgumentException("Invalid Matlab variable name \'" + variableName + "\'");\r
+        \r
+        StructArray result;\r
+        synchronized ( this ) {\r
+            result = getMatlabStructArrayImpl(engineId, variableName);\r
+        }\r
+        \r
+        return result;\r
+    }\r
+    \r
+    /**\r
+     * Set the value of a Matlab variable to a struct array.\r
+     * \r
+     * The given map object must contain array of values of equal length and type, which\r
+     * must be suitable as input any of the type-specific access functions.\r
+     * \r
+     * A row vector is created.\r
+     */\r
+    public void setMatlabStructArray(String variableName, StructArray value) {\r
+        if (value == null)\r
+            throw new IllegalArgumentException("Invalid Matlab array value given");\r
+        \r
+        int result;\r
+        synchronized ( this ) {\r
+            result = setMatlabStructArrayImpl(engineId, variableName, value);\r
+        }\r
+        \r
+        if (result != 0) {\r
+            throw new RuntimeException("Setting Matlab variable value failed");\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Evaluate a Matlab expression.\r
+     */\r
+    public void evaluateMatlabExpression(String expression) {\r
+        int result;\r
+        synchronized ( this ) {\r
+            result = evaluateMatlabExpressionImpl(engineId, expression);\r
+        }\r
+        \r
+        if (result != 0) {\r
+            throw new RuntimeException("Evaluation of Matlab expression failed");\r
+        }\r
+    }\r
+    \r
+    private static native long openMatlabEngineImpl(String workingDirectory);\r
+    private static native void closeMatlabEngineImpl(long engineId);\r
+    \r
+    private static native int evaluateMatlabExpressionImpl(long engineId, String expression);\r
+    \r
+    private static native MatlabArray getMatlabArrayImpl(long engineId, String variableName);\r
+    private static native int setMatlabArrayImpl(long engineId, String variableName, MatlabArray value);  \r
+    \r
+    private static native DoubleArray getMatlabDoubleArrayImpl(long engineId, String variableName);\r
+    private static native int setMatlabDoubleArrayImpl(long engineId, String variableName, DoubleArray value);\r
+    \r
+    private static native CellArray getMatlabCellArrayImpl(long engineId, String variableName);\r
+    private static native int setMatlabCellArrayImpl(long engineId, String variableName, CellArray value);\r
+    \r
+    private static native CharacterArray getMatlabCharacterArrayImpl(long engineId, String variableName);\r
+    private static native int setMatlabCharacterArrayImpl(long engineId, String variableName, CharacterArray value);\r
+    \r
+    private static native StructArray getMatlabStructArrayImpl(long engineId, String variableName);\r
+    private static native int setMatlabStructArrayImpl(long engineId, String variableName, StructArray value);\r
+}\r
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 (file)
index 0000000..9d4adcf
--- /dev/null
@@ -0,0 +1,67 @@
+package org.simantics.matlablink;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.Map;\r
+\r
+import org.simantics.scl.runtime.SCLContext;\r
+import org.simantics.scl.runtime.function.Function;\r
+import org.simantics.scl.runtime.tuple.Tuple0;\r
+\r
+public class Matlab {\r
+    public static final String ENGINE = "Simantics/Matlab/Matlab";\r
+    \r
+    public static Engine openEngine(File workingDirectory) {\r
+        if (workingDirectory == null || !workingDirectory.exists() || !workingDirectory.isDirectory()) {\r
+            throw new IllegalArgumentException("Working directory is not an existing directory");\r
+        }\r
+        \r
+        Engine engine = new Engine(workingDirectory.getAbsolutePath());\r
+        if (!engine.isOpen())\r
+            throw new RuntimeException("Opening Matlab engine failed");\r
+        \r
+        return engine;\r
+    }\r
+    \r
+    @SuppressWarnings( "unchecked" )\r
+    public static Object runMatlab(File workingDirectory, @SuppressWarnings("rawtypes") Function fun) {\r
+        SCLContext context = SCLContext.getCurrent();\r
+        Engine oldEngine = (Engine)context.get(ENGINE);\r
+        try (Engine newEngine = openEngine(workingDirectory)) {\r
+            context.put(ENGINE, newEngine);\r
+            return fun.apply(Tuple0.INSTANCE);\r
+        } catch ( IOException e ) {\r
+            throw new RuntimeException(e);\r
+        }\r
+        finally {\r
+            context.put(ENGINE, oldEngine);\r
+        }\r
+    }\r
+    \r
+    @SuppressWarnings( "unchecked" )\r
+    public static Object runWithEngine(Engine engine, @SuppressWarnings("rawtypes") Function fun) {\r
+        SCLContext context = SCLContext.getCurrent();\r
+        Engine oldEngine = (Engine)context.get(ENGINE);\r
+        try {\r
+            context.put(ENGINE, engine);\r
+            return fun.apply(Tuple0.INSTANCE);\r
+        }\r
+        finally {\r
+            context.put(ENGINE, oldEngine);\r
+        }\r
+    }\r
+    \r
+    @SuppressWarnings( { "unchecked", "rawtypes" } )\r
+    public static Object matchMatlabArray(Object array, Function doubleFun, Function stringFun, Function cellFun, Function structFun) {\r
+        if (array instanceof double[])\r
+            return doubleFun.apply(array);\r
+        else if (array instanceof String)\r
+            return stringFun.apply(array);\r
+        else if (array instanceof Object[])\r
+            return cellFun.apply(array);\r
+        else if (array instanceof Map)\r
+            return structFun.apply(array);\r
+        else\r
+            return null;\r
+    }\r
+}\r
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 (file)
index 0000000..25244e4
--- /dev/null
@@ -0,0 +1,70 @@
+package org.simantics.matlablink;\r
+\r
+import java.util.Map;\r
+\r
+public abstract class MatlabArray {\r
+    public boolean isDouble() {\r
+        return false;\r
+    }\r
+    \r
+    public boolean isCharacter() {\r
+        return false;\r
+    }\r
+    \r
+    public boolean isCell() {\r
+        return false;\r
+    }\r
+    \r
+    public boolean isStruct() {\r
+        return false;\r
+    }\r
+    \r
+    public int size() {\r
+        return 0;\r
+    }\r
+    \r
+    public int[] dims() {\r
+        return null;\r
+    }\r
+    \r
+    public double[] getDoubleValue() {\r
+        return null;\r
+    }\r
+\r
+    public double getDoubleValue(int index) {\r
+        return 0.0;\r
+    }\r
+    \r
+    public String getStringValue() {\r
+        return null;\r
+    }\r
+    \r
+    public MatlabArray[] getCellValue() {\r
+        return null;\r
+    }\r
+    \r
+    public MatlabArray getCellItem(int index) {\r
+        return null;\r
+    }\r
+    \r
+    public MatlabArray getField(int index, String fieldName) {\r
+        return null;\r
+    }\r
+    \r
+    public Map<String, MatlabArray> getStructItem(int index) {\r
+        return null;\r
+    }\r
+    \r
+    public interface Visitor {\r
+        public void visit(DoubleArray value);\r
+        public void visit(CellArray value);\r
+        public void visit(CharacterArray value);\r
+        public void visit(StructArray value);\r
+    }\r
+    \r
+    @Override\r
+    abstract public boolean equals( Object obj );\r
+    \r
+    @Override\r
+    abstract public String toString();\r
+}\r
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 (file)
index 0000000..a0f4043
--- /dev/null
@@ -0,0 +1,148 @@
+package org.simantics.matlablink;\r
+\r
+import java.util.Arrays;\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+public class StructArray extends MatlabArray {\r
+    int size;\r
+    Map<String, MatlabArray[]> fields;\r
+    int[] dims;\r
+\r
+    public StructArray(int size, String[] fields) {\r
+        this.size = size;\r
+        this.dims = new int[] {1, size};\r
+        this.fields = new HashMap<String, MatlabArray[]>();\r
+        for (String name : fields) {\r
+            this.fields.put(name, new MatlabArray[size]);\r
+        }\r
+    }\r
+    \r
+    public StructArray(int size, Collection<String> fields) {\r
+        this.size = size;\r
+        this.dims = new int[] {1, size};\r
+        this.fields = new HashMap<String, MatlabArray[]>();\r
+        for (String name : fields) {\r
+            this.fields.put(name, new MatlabArray[size]);\r
+        }\r
+    }\r
+    \r
+    public StructArray(int[] dims, String[] fields) {\r
+        this.dims = dims;\r
+        int size = 1;\r
+        for (int n : dims) size *= n;\r
+        this.size = size;\r
+        \r
+        this.fields = new HashMap<String, MatlabArray[]>();\r
+        for (String name : fields) {\r
+            this.fields.put(name, new MatlabArray[size]);\r
+        }\r
+    }\r
+    \r
+    public StructArray(int[] dims, Collection<String> fields) {\r
+        this.dims = dims;\r
+        int size = 1;\r
+        for (int n : dims) size *= n;\r
+        this.size = size;\r
+        \r
+        this.fields = new HashMap<String, MatlabArray[]>();\r
+        for (String name : fields) {\r
+            this.fields.put(name, new MatlabArray[size]);\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    public boolean isStruct() {\r
+        return true;\r
+    }\r
+    \r
+    @Override\r
+    public int size() {\r
+        return size;\r
+    }\r
+    \r
+    @Override\r
+    public int[] dims() {\r
+        return dims;\r
+    }\r
+    \r
+    public String[] getFields() {\r
+        return fields.keySet().toArray(new String[fields.size()]);\r
+    }\r
+    \r
+    @Override\r
+    public MatlabArray getField(int index, String fieldName) {\r
+        MatlabArray[] value = fields.get( fieldName );\r
+        return value != null ? value[index] : null;\r
+    }\r
+    \r
+    public MatlabArray getField(String fieldName, int... is) {\r
+        int index = 0;\r
+        int s = 1;\r
+        for (int k = 0; k < is.length; k++) {\r
+            index = index + s * is[k];\r
+            s *= dims[k];\r
+        }\r
+        \r
+        return getField(index, fieldName);\r
+    }\r
+\r
+    public void setField(int index, String fieldName, MatlabArray v) {\r
+        MatlabArray[] value = fields.get( fieldName );\r
+        if (value == null) {\r
+            value = new MatlabArray[size];\r
+            value[index] = v;\r
+            fields.put( fieldName, value );\r
+        }\r
+        value[index] = v;\r
+    }\r
+    \r
+    public void setField(String fieldName, MatlabArray v, int... is) {\r
+        int index = 0;\r
+        int s = 1;\r
+        for (int k = 0; k < is.length; k++) {\r
+            index = index + s * is[k];\r
+            s *= dims[k];\r
+        }\r
+\r
+        setField(index, fieldName, v);\r
+    }\r
+    \r
+    @Override\r
+    public boolean equals( Object obj ) {\r
+        return obj instanceof StructArray &&\r
+               Arrays.equals(this.dims, ((StructArray)obj).dims) &&\r
+               fieldsEqual(this.fields, ((StructArray)obj).fields);\r
+    }\r
+    \r
+    private static boolean fieldsEqual( Map<String, MatlabArray[]> f1, Map<String, MatlabArray[]> f2 ) {\r
+        if (!f1.keySet().equals(f2.keySet()))\r
+            return false;\r
+        return Arrays.deepEquals(f1.values().toArray(), f2.values().toArray());\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        StringBuilder sb = new StringBuilder();\r
+        sb.append("{");\r
+        Set<String> keys = fields.keySet();\r
+        Iterator<String> iter = keys.iterator();\r
+        for (int i = 0; i < fields.entrySet().size(); i++) {\r
+            String key = iter.next();\r
+            if (i > 0) sb.append(", ");\r
+            sb.append(key);\r
+        }\r
+        \r
+        sb.append(" (");\r
+        for (int i = 0; i < dims.length; i++) {\r
+            if (i > 0) sb.append("x");\r
+            sb.append( dims[i] );\r
+        }\r
+        sb.append(")}");\r
+        \r
+        return sb.toString();\r
+    }\r
+}\r
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 (file)
index 0000000..cae75fc
--- /dev/null
@@ -0,0 +1,267 @@
+package org.simantics.matlablink.test;\r
+\r
+import static org.junit.Assert.assertArrayEquals;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertTrue;\r
+import static org.junit.Assert.fail;\r
+\r
+import java.nio.file.Files;\r
+import java.nio.file.Path;\r
+\r
+import org.junit.AfterClass;\r
+import org.junit.BeforeClass;\r
+import org.junit.Test;\r
+import org.simantics.matlablink.CellArray;\r
+import org.simantics.matlablink.CharacterArray;\r
+import org.simantics.matlablink.DoubleArray;\r
+import org.simantics.matlablink.Engine;\r
+import org.simantics.matlablink.Matlab;\r
+import org.simantics.matlablink.MatlabArray;\r
+import org.simantics.matlablink.StructArray;\r
+\r
+public class TestMatlabEngine {\r
+\r
+    Engine engine;\r
+    Path tempDir;\r
+    \r
+    @BeforeClass\r
+    public void setUp() throws Exception {\r
+        tempDir = Files.createTempDirectory( "testMatlabEngine" );\r
+        engine = Matlab.openEngine(tempDir.toFile());\r
+    }\r
+\r
+    @AfterClass\r
+    public void tearDown() throws Exception {\r
+        engine.close();\r
+        tempDir.toFile().delete();\r
+    }\r
+\r
+    @Test\r
+    public void testDoubleArray() {\r
+        double[] values = new double[] { 1, 2, 3 };\r
+        engine.setMatlabDoubleArray("foo", new DoubleArray(values));\r
+        DoubleArray returnedValues = engine.getMatlabDoubleArray("foo");\r
+        \r
+        assertArrayEquals(new int[] { 1, 3 }, returnedValues.dims());\r
+        assertArrayEquals(values, returnedValues.getDoubleValue(), 0.0);\r
+    }\r
+\r
+    @Test\r
+    public void testCharacterArray() {\r
+        String value = "Hello world! (ã�“ã‚“ã�«ã�¡ã�¯ä¸–ç•Œ!)";\r
+        engine.setMatlabCharacterArray("foo", new CharacterArray(value));\r
+        CharacterArray returnedValue = engine.getMatlabCharacterArray("foo");\r
+        \r
+        assertEquals(value, returnedValue.getStringValue());\r
+    }\r
+    \r
+    @Test\r
+    public void testCellArray() {\r
+        CellArray value = new CellArray( 2 );\r
+        value.setCellItem(0, new DoubleArray(new double[] { 1, 2 }));\r
+        value.setCellItem(1, new CharacterArray("Booyah!"));\r
+        \r
+        engine.setMatlabCellArray("foo", value);\r
+        CellArray returnedValues = engine.getMatlabCellArray("foo");\r
+        \r
+        assertEquals(value, returnedValues);\r
+    }\r
+    \r
+    @Test\r
+    public void testStructArray() {\r
+        String[] fields = new String[] {"field_1", "field_2"};\r
+        StructArray value = new StructArray(2, fields);\r
+        value.setField(0, fields[0], new DoubleArray(new double[] { 1, 2, 3, 4 }));\r
+        value.setField(1, fields[0], new DoubleArray(new double[] { 2, 4, 6, }));\r
+        value.setField(0, fields[1], new CharacterArray("foo"));\r
+        value.setField(1, fields[1], new CharacterArray("bar"));\r
+        \r
+        engine.setMatlabStructArray("foo", value);\r
+        StructArray returnedValues = engine.getMatlabStructArray("foo");\r
+        \r
+        assertEquals(value, returnedValues);\r
+    }\r
+    \r
+    @Test\r
+    public void testEvaluation1() {\r
+        engine.evaluateMatlabExpression("bar = [1 2 3];");\r
+        DoubleArray returnedValues = engine.getMatlabDoubleArray("bar");\r
+        \r
+        assertArrayEquals(new double[] {1, 2, 3}, returnedValues.getDoubleValue(), 0.0);\r
+    }\r
+    \r
+    @Test\r
+    public void testEvaluation2() {\r
+        engine.setMatlabDoubleArray("foo", new DoubleArray(new double[] { 1, 2, 3 }));        \r
+        engine.evaluateMatlabExpression("bar = foo + 1;");\r
+        DoubleArray returnedValues = engine.getMatlabDoubleArray("bar");\r
+        \r
+        assertArrayEquals(new double[] {2, 3, 4}, returnedValues.getDoubleValue(), 0.0);\r
+    }\r
+    \r
+    @Test\r
+    public void testIncompatible1() {\r
+        engine.evaluateMatlabExpression("a = {'foo', 'bar'};");\r
+        try {\r
+            engine.getMatlabDoubleArray("a");\r
+            fail("Expected exception");\r
+        } catch (Exception e) {\r
+            assertEquals( "Variable not a double array", e.getMessage() );\r
+        }\r
+    }\r
+    \r
+    @Test\r
+    public void testIncompatible2() {\r
+        engine.evaluateMatlabExpression("a = {'foo', 'bar'};");\r
+        try {\r
+            engine.getMatlabCharacterArray("a");\r
+            fail("Expected exception");\r
+        } catch (Exception e) {\r
+            assertEquals( "Variable not a character array", e.getMessage() );\r
+        }\r
+    }\r
+    \r
+    @Test\r
+    public void testIncompatible3() {\r
+        engine.evaluateMatlabExpression("a = {'foo', 'bar'};");\r
+        try {\r
+            engine.getMatlabStructArray("a");\r
+            fail("Expected exception");\r
+        } catch (Exception e) {\r
+            assertEquals( "Variable not a struct array", e.getMessage() );\r
+        }\r
+    }\r
+    \r
+    @Test\r
+    public void testIncompatible4() {\r
+        engine.evaluateMatlabExpression("a = [1 2];");\r
+        try {\r
+            engine.getMatlabCellArray("a");\r
+            fail("Expected exception");\r
+        } catch (Exception e) {\r
+            assertEquals( "Variable not a cell array", e.getMessage() );\r
+        }\r
+    }\r
+    \r
+    \r
+    @Test\r
+    public void testIncompatible5() {\r
+        engine.evaluateMatlabExpression("a = [1 2];");\r
+        try {\r
+            engine.getMatlabCharacterArray("a");\r
+            fail("Expected exception");\r
+        } catch (Exception e) {\r
+            assertEquals( "Variable not a character array", e.getMessage() );\r
+        }\r
+    }    \r
+    \r
+    @Test\r
+    public void testIncompatible6() {\r
+        engine.evaluateMatlabExpression("a = [1 2];");\r
+        try {\r
+            engine.getMatlabStructArray("a");\r
+            fail("Expected exception");\r
+        } catch (Exception e) {\r
+            assertEquals( "Variable not a struct array", e.getMessage() );\r
+        }\r
+    }\r
+    \r
+    @Test\r
+    public void testIncompatible7() {\r
+        engine.evaluateMatlabExpression("a = 'foobar';");\r
+        try {\r
+            engine.getMatlabDoubleArray("a");\r
+            fail("Expected exception");\r
+        } catch (Exception e) {\r
+            assertEquals( "Variable not a double array", e.getMessage() );\r
+        }\r
+    }    \r
+    \r
+    @Test\r
+    public void testIncompatible8() {\r
+        engine.evaluateMatlabExpression("a = 'foobar';");\r
+        try {\r
+            engine.getMatlabCellArray("a");\r
+            fail("Expected exception");\r
+        } catch (Exception e) {\r
+            assertEquals( "Variable not a cell array", e.getMessage() );\r
+        }\r
+    }\r
+    \r
+    @Test\r
+    public void testIncompatible9() {\r
+        engine.evaluateMatlabExpression("a = 'foobar';");\r
+        try {\r
+            engine.getMatlabStructArray("a");\r
+            fail("Expected exception");\r
+        } catch (Exception e) {\r
+            assertEquals( "Variable not a struct array", e.getMessage() );\r
+        }\r
+    }\r
+    \r
+    @Test\r
+    public void testIncompatible10() {\r
+        engine.evaluateMatlabExpression("a = []; a.field = 1;");\r
+        try {\r
+            engine.getMatlabDoubleArray("a");\r
+            fail("Expected exception");\r
+        } catch (Exception e) {\r
+            assertEquals( "Variable not a double array", e.getMessage() );\r
+        }\r
+    }\r
+    \r
+    @Test\r
+    public void testIncompatible11() {\r
+        engine.evaluateMatlabExpression("a = []; a.field = 1;");\r
+        try {\r
+            engine.getMatlabCharacterArray("a");\r
+            fail("Expected exception");\r
+        } catch (Exception e) {\r
+            assertEquals( "Variable not a character array", e.getMessage() );\r
+        }\r
+    }\r
+    \r
+    @Test\r
+    public void testIncompatible12() {\r
+        engine.evaluateMatlabExpression("a = []; a.field = 1;");\r
+        try {\r
+            engine.getMatlabCellArray("a");\r
+            fail("Expected exception");\r
+        } catch (Exception e) {\r
+            assertEquals( "Variable not a cell array", e.getMessage() );\r
+        }\r
+    }\r
+    \r
+    @Test\r
+    public void testGeneric1() {\r
+        engine.evaluateMatlabExpression("a = [1, 2, 3, 4];");\r
+        MatlabArray result = engine.getMatlabArray("a");\r
+        assertTrue(result instanceof DoubleArray);\r
+        assertArrayEquals(new double[] { 1, 2, 3, 4 }, result.getDoubleValue(), 0.0);\r
+    }\r
+\r
+    @Test\r
+    public void testGeneric2() {\r
+        engine.evaluateMatlabExpression("a = 'foobar';");\r
+        MatlabArray result = engine.getMatlabArray("a");\r
+        assertTrue(result instanceof CharacterArray);\r
+        assertEquals("foobar", result.getStringValue());\r
+    }\r
+\r
+    @Test\r
+    public void testGeneric3() {\r
+        engine.evaluateMatlabExpression("a = { struct('foo', 1), 'bar' };");\r
+        MatlabArray a = engine.getMatlabArray("a");\r
+        \r
+        assertTrue(a instanceof CellArray);\r
+        MatlabArray a_1 = a.getCellItem(0);\r
+        MatlabArray a_2 = a.getCellItem(1);\r
+        assertTrue(a_1 instanceof StructArray);\r
+        assertTrue(a_2 instanceof CharacterArray);\r
+        MatlabArray a_1_foo = a_1.getField(0, "foo");\r
+        assertTrue(a_1_foo instanceof DoubleArray);\r
+        assertEquals(1, a_1_foo.size());\r
+        assertArrayEquals(new double[] {1}, a_1_foo.getDoubleValue(), 0.0);\r
+        assertEquals("bar", a_2.getStringValue());\r
+    }\r
+}\r