1 ///////////////////////////////////////////////////////
\r
3 // VTT Technical Research Centre of Finland LTD //
\r
4 // For internal use only. Do not redistribute. //
\r
7 // Antton Tapani ext-antton.tapani@vtt.fi //
\r
9 // Last modified by Antton Tapani 9.2016 //
\r
11 ///////////////////////////////////////////////////////
\r
15 #include <windows.h>
\r
17 jint throwException( JNIEnv *env, char *className, char *message )
\r
19 jclass exClass = (*env)->FindClass( env, className);
\r
20 if (exClass == NULL) {
\r
24 return (*env)->ThrowNew( env, exClass, message );
\r
27 jint throwPythonException( JNIEnv *env, char *message ) {
\r
28 return throwException( env, PYTHON_EXCEPTION, message );
\r
31 jint throwIllegalArgumentException( JNIEnv *env, char *message ) {
\r
32 return throwException( env, ILLEGAL_ARGUMENT_EXCEPTION, message );
\r
35 int moduleCount = 0;
\r
39 JNIEXPORT jlong JNICALL Java_org_simantics_pythonlink_PythonContext_createContextImpl(JNIEnv *env, jobject thisObj) {
\r
46 hasNumpy = _import_array();
\r
47 hasNumpy = hasNumpy != -1;
\r
50 sprintf(name, "SCL_%d", ++moduleCount);
\r
53 PyObject *module = PyModule_New(name);
\r
54 PyObject *main = PyImport_AddModule("__main__");
\r
56 PyDict_Merge(PyModule_GetDict(module), PyModule_GetDict(main), 0);
\r
58 return (jlong)module;
\r
62 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_deleteContextImpl(JNIEnv *env, jobject thisObj, jlong contextID) {
\r
63 PyObject *module = (PyObject*)contextID;
\r
67 PyObject *getPythonBool(jboolean value) {
\r
76 PyObject *getPythonString(JNIEnv *env, jstring string) {
\r
77 jsize len = (*env)->GetStringLength(env, string);
\r
78 const jchar *chars = (*env)->GetStringChars(env, string, NULL);
\r
80 PyObject *value = PyUnicode_DecodeUTF16((char*)chars, 2*len, NULL, NULL);
\r
82 (*env)->ReleaseStringChars(env, string, chars);
\r
86 PyObject *getPythonStringList(JNIEnv *env, jobjectArray value) {
\r
87 jsize nitems = (*env)->GetArrayLength(env, value);
\r
88 jint *values = (*env)->GetIntArrayElements(env, value, NULL);
\r
89 jclass stringClass = (*env)->FindClass(env, STRING_CLASS);
\r
92 PyObject *result = PyList_New(nitems);
\r
93 for (i = 0; i < nitems; i++) {
\r
94 jobject item = (*env)->GetObjectArrayElement(env, value, i);
\r
95 if (item != NULL && (*env)->IsInstanceOf(env, item, stringClass)) {
\r
96 PyList_SetItem(result, i, getPythonString(env, (jstring)item));
\r
99 PyList_SetItem(result, i, Py_None);
\r
103 (*env)->ReleaseIntArrayElements(env, value, values, JNI_ABORT);
\r
107 PyObject *getPythonBooleanList(JNIEnv *env, jbooleanArray value) {
\r
108 jsize nitems = (*env)->GetArrayLength(env, value);
\r
109 jboolean *values = (*env)->GetBooleanArrayElements(env, value, NULL);
\r
112 PyObject *result = PyList_New(nitems);
\r
113 for (i = 0; i < nitems; i++) {
\r
114 PyList_SetItem(result, i, getPythonBool(values[i]));
\r
117 (*env)->ReleaseBooleanArrayElements(env, value, values, JNI_ABORT);
\r
121 PyObject *getPythonByteArray(JNIEnv *env, jbyteArray value) {
\r
122 jint len = (*env)->GetArrayLength(env, value);
\r
123 jbyte *values = (*env)->GetByteArrayElements(env, value, NULL);
\r
125 PyObject *result = PyByteArray_FromStringAndSize(values, len);
\r
127 (*env)->ReleaseByteArrayElements(env, value, values, JNI_ABORT);
\r
131 PyObject *getPythonIntegerList(JNIEnv *env, jintArray value) {
\r
132 jsize nitems = (*env)->GetArrayLength(env, value);
\r
133 jint *values = (*env)->GetIntArrayElements(env, value, NULL);
\r
136 PyObject *result = PyList_New(nitems);
\r
137 for (i = 0; i < nitems; i++) {
\r
138 PyList_SetItem(result, i, PyLong_FromLong(values[i]));
\r
141 (*env)->ReleaseIntArrayElements(env, value, values, JNI_ABORT);
\r
145 PyObject *getPythonLongList(JNIEnv *env, jlongArray value) {
\r
146 jsize nitems = (*env)->GetArrayLength(env, value);
\r
147 jlong *values = (*env)->GetLongArrayElements(env, value, NULL);
\r
150 PyObject *result = PyList_New(nitems);
\r
151 for (i = 0; i < nitems; i++) {
\r
152 PyList_SetItem(result, i, PyLong_FromLongLong(values[i]));
\r
155 (*env)->ReleaseLongArrayElements(env, value, values, JNI_ABORT);
\r
159 PyObject *getPythonFloatList(JNIEnv *env, jfloatArray value) {
\r
160 jsize nitems = (*env)->GetArrayLength(env, value);
\r
161 float *values = (*env)->GetFloatArrayElements(env, value, NULL);
\r
164 PyObject *result = PyList_New(nitems);
\r
165 for (i = 0; i < nitems; i++) {
\r
166 PyList_SetItem(result, i, PyFloat_FromDouble((double)values[i]));
\r
169 (*env)->ReleaseFloatArrayElements(env, value, values, JNI_ABORT);
\r
173 PyObject *getPythonDoubleList(JNIEnv *env, jdoubleArray value) {
\r
174 jsize nitems = (*env)->GetArrayLength(env, value);
\r
175 double *values = (*env)->GetDoubleArrayElements(env, value, NULL);
\r
178 PyObject *result = PyList_New(nitems);
\r
179 for (i = 0; i < nitems; i++) {
\r
180 PyList_SetItem(result, i, PyFloat_FromDouble(values[i]));
\r
183 (*env)->ReleaseDoubleArrayElements(env, value, values, JNI_ABORT);
\r
187 PyObject *getPythonNDArray(JNIEnv *env, jobject value) {
\r
188 jclass ndarrayClass = (*env)->FindClass(env, NDARRAY_CLASS);
\r
189 jmethodID dimsMethod = (*env)->GetMethodID(env, ndarrayClass, "dims", "()[I");
\r
190 jmethodID getValuesMethod = (*env)->GetMethodID(env, ndarrayClass, "getValues", "()[D");
\r
192 jintArray jdims = (*env)->CallObjectMethod(env, value, dimsMethod);
\r
193 jsize ndims = (*env)->GetArrayLength(env, jdims);
\r
194 jint *dims = (*env)->GetIntArrayElements(env, jdims, NULL);
\r
196 jdoubleArray jvalues = (*env)->CallObjectMethod(env, value, getValuesMethod);
\r
197 jsize len = (*env)->GetArrayLength(env, jvalues);
\r
198 jdouble *values = (*env)->GetDoubleArrayElements(env, jvalues, NULL);
\r
200 npy_intp *pyDims = (npy_intp*)malloc(ndims * sizeof(npy_intp));
\r
202 jint i, nelem = ndims > 0 ? 1 : 0;
\r
203 for (i = 0; i < ndims; i++) {
\r
205 pyDims[i] = dims[i];
\r
208 len = min(len, nelem);
\r
211 PyObject *array = PyArray_EMPTY(ndims, pyDims, NPY_DOUBLE, 0);
\r
212 double *data = (double *)PyArray_DATA((PyArrayObject*)array);
\r
214 memcpy(data, values, len * sizeof(double));
\r
218 (*env)->ReleaseDoubleArrayElements(env, jvalues, values, JNI_ABORT);
\r
219 (*env)->ReleaseIntArrayElements(env, jdims, dims, JNI_ABORT);
\r
225 PyObject *getPythonBooleanObject(JNIEnv *env, jobject object, jobject binding) {
\r
226 jclass bindingClass = (*env)->FindClass(env, BOOLEANBINDING_CLASS);
\r
227 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)Z");
\r
229 jboolean bvalue = (*env)->CallBooleanMethod(env, binding, getValueMethod, object);
\r
230 return getPythonBool(bvalue);
\r
233 PyObject *getPythonByteObject(JNIEnv *env, jobject object, jobject binding) {
\r
234 jclass bindingClass = (*env)->FindClass(env, BYTEBINDING_CLASS);
\r
235 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)B");
\r
237 jbyte v = (*env)->CallByteMethod(env, binding, getValueMethod, object);
\r
238 return PyLong_FromLong(v);
\r
241 PyObject *getPythonIntegerObject(JNIEnv *env, jobject object, jobject binding) {
\r
242 jclass bindingClass = (*env)->FindClass(env, INTEGERBINDING_CLASS);
\r
243 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)I");
\r
245 jint v = (*env)->CallIntMethod(env, binding, getValueMethod, object);
\r
246 return PyLong_FromLong(v);
\r
249 PyObject *getPythonLongObject(JNIEnv *env, jobject object, jobject binding) {
\r
250 jclass bindingClass = (*env)->FindClass(env, LONGBINDING_CLASS);
\r
251 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)J");
\r
253 jlong v = (*env)->CallLongMethod(env, binding, getValueMethod, object);
\r
254 return PyLong_FromLongLong(v);
\r
257 PyObject *getPythonFloatObject(JNIEnv *env, jobject object, jobject binding) {
\r
258 jclass bindingClass = (*env)->FindClass(env, FLOATBINDING_CLASS);
\r
259 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)F");
\r
261 jfloat v = (*env)->CallFloatMethod(env, binding, getValueMethod, object);
\r
262 return PyFloat_FromDouble(v);
\r
265 PyObject *getPythonDoubleObject(JNIEnv *env, jobject object, jobject binding) {
\r
266 jclass bindingClass = (*env)->FindClass(env, DOUBLEBINDING_CLASS);
\r
267 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)D");
\r
269 jdouble v = (*env)->CallDoubleMethod(env, binding, getValueMethod, object);
\r
270 return PyFloat_FromDouble(v);
\r
273 PyObject *getPythonStringObject(JNIEnv *env, jobject object, jobject binding) {
\r
274 jclass bindingClass = (*env)->FindClass(env, STRINGBINDING_CLASS);
\r
275 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue", "(L" OBJECT_CLASS ";)L" STRING_CLASS ";");
\r
277 jobject string = (*env)->CallObjectMethod(env, binding, getValueMethod, object);
\r
278 jsize len = (*env)->GetStringLength(env, string);
\r
279 const jchar *chars = (*env)->GetStringChars(env, string, NULL);
\r
281 PyObject *value = PyUnicode_DecodeUTF16((char*)chars, 2*len, NULL, NULL);
\r
283 (*env)->ReleaseStringChars(env, string, chars);
\r
287 PyObject *getPythonRecordObject(JNIEnv *env, jobject object, jobject binding) {
\r
288 jclass bindingClass = (*env)->FindClass(env, RECORDBINDING_CLASS);
\r
289 jmethodID typeMethod = (*env)->GetMethodID(env, bindingClass, "type", "()L" RECORDTYPE_CLASS ";");
\r
290 jmethodID getComponent = (*env)->GetMethodID(env, bindingClass, "getComponent", "(L" OBJECT_CLASS ";I)L" OBJECT_CLASS ";");
\r
291 jmethodID getComponentBinding = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "(I)L" BINDING_CLASS ";");
\r
293 jclass recordType = (*env)->FindClass(env, RECORDTYPE_CLASS);
\r
294 jmethodID getTypeComponent = (*env)->GetMethodID(env, recordType, "getComponent", "(I)L" COMPONENT_CLASS ";");
\r
295 jmethodID getComponentCount = (*env)->GetMethodID(env, recordType, "getComponentCount", "()I");
\r
297 jclass componentClass = (*env)->FindClass(env, COMPONENT_CLASS);
\r
298 jfieldID nameField = (*env)->GetFieldID(env, componentClass, "name", "L" STRING_CLASS ";");
\r
300 jobject type = (*env)->CallObjectMethod(env, binding, typeMethod);
\r
301 jint n = (*env)->CallIntMethod(env, type, getComponentCount);
\r
304 PyObject *result = PyDict_New();
\r
305 for (i = 0; i < n; i++) {
\r
306 jobject recordTypeComponent = (*env)->CallObjectMethod(env, type, getComponent, i);
\r
307 jstring fieldName = (jstring)(*env)->GetObjectField(env, recordTypeComponent, nameField);
\r
308 jobject componentObject = (*env)->CallObjectMethod(env, binding, getComponent, object, i);
\r
309 jobject componentBinding = (*env)->CallObjectMethod(env, binding, getComponentBinding, i);
\r
311 PyObject *item = getPythonObject(env, componentObject, componentBinding);
\r
312 PyDict_SetItem(result, getPythonString(env, fieldName), item);
\r
318 PyObject *getPythonArrayObject(JNIEnv *env, jobject object, jobject binding) {
\r
319 jclass bindingClass = (*env)->FindClass(env, ARRAYBINDING_CLASS);
\r
320 jmethodID componentBindingMethod = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "()L" BINDING_CLASS ";");
\r
321 jmethodID sizeMethod = (*env)->GetMethodID(env, bindingClass, "size", "(L" OBJECT_CLASS ";)I");
\r
322 jmethodID getMethod = (*env)->GetMethodID(env, bindingClass, "get", "(L" OBJECT_CLASS ";I)L" OBJECT_CLASS ";");
\r
324 jobject componentBinding = (*env)->CallObjectMethod(env, binding, componentBindingMethod);
\r
326 jint size = (*env)->CallIntMethod(env, binding, sizeMethod, object);
\r
328 PyObject *result = PyList_New(size);
\r
331 for (i = 0; i < size; i++) {
\r
332 jobject item = (*env)->CallObjectMethod(env, binding, getMethod, object, i);
\r
334 PyList_SetItem(result, i, getPythonObject(env, item, componentBinding));
\r
336 PyList_SetItem(result, i, Py_None);
\r
342 PyObject *getPythonMapObject(JNIEnv *env, jobject object, jobject binding) {
\r
343 jclass objectClass = (*env)->FindClass(env, OBJECT_CLASS);
\r
344 jclass bindingClass = (*env)->FindClass(env, MAPBINDING_CLASS);
\r
345 jmethodID getKeyBindingMethod = (*env)->GetMethodID(env, bindingClass, "getKeyBinding", "()L" BINDING_CLASS ";");
\r
346 jmethodID getValueBindingMethod = (*env)->GetMethodID(env, bindingClass, "getValueBinding", "()L" BINDING_CLASS ";");
\r
347 jmethodID sizeMethod = (*env)->GetMethodID(env, bindingClass, "size", "(L" OBJECT_CLASS ";)I");
\r
348 jmethodID getAllMethod = (*env)->GetMethodID(env, bindingClass, "getAll", "(L" OBJECT_CLASS ";[L" OBJECT_CLASS ";[L" OBJECT_CLASS ";)V");
\r
350 jobject keyBinding = (*env)->CallObjectMethod(env, binding, getKeyBindingMethod);
\r
351 jobject valueBinding = (*env)->CallObjectMethod(env, binding, getValueBindingMethod);
\r
353 jint size = (*env)->CallIntMethod(env, binding, sizeMethod, object);
\r
354 jobjectArray keys = (*env)->NewObjectArray(env, size, objectClass, NULL);
\r
355 jobjectArray values = (*env)->NewObjectArray(env, size, objectClass, NULL);
\r
357 PyObject *result = PyDict_New();
\r
360 (*env)->CallVoidMethod(env, binding, getAllMethod, object, keys, values);
\r
362 for (i = 0; i < size; i++) {
\r
363 jobject key = (*env)->GetObjectArrayElement(env, keys, i);
\r
364 jobject item = (*env)->GetObjectArrayElement(env, values, i);
\r
365 PyDict_SetItem(result, getPythonObject(env, key, keyBinding), getPythonObject(env, item, valueBinding));
\r
368 (*env)->DeleteLocalRef(env, keys);
\r
369 (*env)->DeleteLocalRef(env, values);
\r
374 PyObject *getPythonOptionalObject(JNIEnv *env, jobject object, jobject binding) {
\r
375 jclass bindingClass = (*env)->FindClass(env, OPTIONALBINDING_CLASS);
\r
376 jmethodID hasValueMethod = (*env)->GetMethodID(env, bindingClass, "hasValue", "(L" OBJECT_CLASS ";)Z");
\r
378 jboolean hasValue = (*env)->CallBooleanMethod(env, binding, hasValueMethod, object);
\r
381 jmethodID componentBindingMethod = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "()L" BINDING_CLASS ";");
\r
382 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "hasValue", "(L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");
\r
384 jobject componentBinding = (*env)->CallObjectMethod(env, binding, componentBindingMethod);
\r
385 jobject value = (*env)->CallObjectMethod(env, binding, getValueMethod, object);
\r
387 return getPythonObject(env, value, componentBinding);
\r
394 PyObject *getPythonUnionObject(JNIEnv *env, jobject object, jobject binding) {
\r
395 jclass bindingClass = (*env)->FindClass(env, UNIONBINDING_CLASS);
\r
396 jmethodID typeMethod = (*env)->GetMethodID(env, bindingClass, "type", "()L" RECORDTYPE_CLASS ";");
\r
397 jmethodID getTagMethod = (*env)->GetMethodID(env, bindingClass, "getTag", "(L" OBJECT_CLASS ";)I");
\r
398 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue", "(L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");
\r
399 jmethodID getComponentBinding = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "(I)L" BINDING_CLASS ";");
\r
401 jclass unionType = (*env)->FindClass(env, UNIONTYPE_CLASS);
\r
402 jmethodID getTypeComponent = (*env)->GetMethodID(env, unionType, "getComponent", "(I)L" COMPONENT_CLASS ";");
\r
404 jclass componentClass = (*env)->FindClass(env, COMPONENT_CLASS);
\r
405 jfieldID nameField = (*env)->GetFieldID(env, componentClass, "name", "L" STRING_CLASS ";");
\r
407 jint tag = (*env)->CallIntMethod(env, binding, getTagMethod, object);
\r
408 jobject value = (*env)->CallObjectMethod(env, binding, getValueMethod, object);
\r
410 jobject type = (*env)->CallObjectMethod(env, binding, typeMethod);
\r
411 jobject typeComponent = (*env)->CallObjectMethod(env, type, getTypeComponent, tag);
\r
412 jstring compName = (*env)->GetObjectField(env, typeComponent, nameField);
\r
414 jobject componentBinding = (*env)->CallObjectMethod(env, binding, getComponentBinding, tag);
\r
416 PyObject *result = PyTuple_New(2);
\r
417 PyTuple_SetItem(result, 0, getPythonString(env, compName));
\r
418 PyTuple_SetItem(result, 1, getPythonObject(env, value, componentBinding));
\r
423 PyObject *getPythonVariantObject(JNIEnv *env, jobject object, jobject binding) {
\r
424 jclass bindingClass = (*env)->FindClass(env, VARIANTBINDING_CLASS);
\r
425 jmethodID getContentMethod = (*env)->GetMethodID(env, bindingClass, "getContent", "(L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");
\r
426 jmethodID getContentBindingMethod = (*env)->GetMethodID(env, bindingClass, "getContentBinding", "(L" OBJECT_CLASS ";)L" BINDING_CLASS ";");
\r
428 jobject content = (*env)->CallObjectMethod(env, binding, getContentMethod, object);
\r
429 jobject contentBinding = (*env)->CallObjectMethod(env, binding, getContentBindingMethod, object);
\r
431 return getPythonObject(env, content, contentBinding);
\r
434 PyObject *getPythonObject(JNIEnv *env, jobject value, jobject binding) {
\r
435 jclass booleanBinding = (*env)->FindClass(env, BOOLEANBINDING_CLASS);
\r
436 jclass byteBinding = (*env)->FindClass(env, BYTEBINDING_CLASS);
\r
437 jclass integerBinding = (*env)->FindClass(env, INTEGERBINDING_CLASS);
\r
438 jclass longBinding = (*env)->FindClass(env, LONGBINDING_CLASS);
\r
439 jclass floatBinding = (*env)->FindClass(env, FLOATBINDING_CLASS);
\r
440 jclass doubleBinding = (*env)->FindClass(env, DOUBLEBINDING_CLASS);
\r
441 jclass stringBinding = (*env)->FindClass(env, STRINGBINDING_CLASS);
\r
442 jclass recordBinding = (*env)->FindClass(env, RECORDBINDING_CLASS);
\r
443 jclass arrayBinding = (*env)->FindClass(env, ARRAYBINDING_CLASS);
\r
444 jclass mapBinding = (*env)->FindClass(env, MAPBINDING_CLASS);
\r
445 jclass optionalBinding = (*env)->FindClass(env, OPTIONALBINDING_CLASS);
\r
446 jclass untionBinding = (*env)->FindClass(env, UNIONBINDING_CLASS);
\r
447 jclass variantBinding = (*env)->FindClass(env, VARIANTBINDING_CLASS);
\r
452 if ((*env)->IsInstanceOf(env, binding, booleanBinding)) {
\r
453 return getPythonBooleanObject(env, value, binding);
\r
455 else if ((*env)->IsInstanceOf(env, binding, byteBinding)) {
\r
456 return getPythonByteObject(env, value, binding);
\r
458 else if ((*env)->IsInstanceOf(env, binding, integerBinding)) {
\r
459 return getPythonIntegerObject(env, value, binding);
\r
461 else if ((*env)->IsInstanceOf(env, binding, longBinding)) {
\r
462 return getPythonLongObject(env, value, binding);
\r
464 else if ((*env)->IsInstanceOf(env, binding, floatBinding)) {
\r
465 return getPythonFloatObject(env, value, binding);
\r
467 else if ((*env)->IsInstanceOf(env, binding, doubleBinding)) {
\r
468 return getPythonDoubleObject(env, value, binding);
\r
470 else if ((*env)->IsInstanceOf(env, binding, stringBinding)) {
\r
471 return getPythonStringObject(env, value, binding);
\r
473 else if ((*env)->IsInstanceOf(env, binding, recordBinding)) {
\r
474 return getPythonRecordObject(env, value, binding);
\r
476 else if ((*env)->IsInstanceOf(env, binding, arrayBinding)) {
\r
477 return getPythonArrayObject(env, value, binding);
\r
479 else if ((*env)->IsInstanceOf(env, binding, mapBinding)) {
\r
480 return getPythonMapObject(env, value, binding);
\r
482 else if ((*env)->IsInstanceOf(env, binding, optionalBinding)) {
\r
483 return getPythonOptionalObject(env, value, binding);
\r
485 else if ((*env)->IsInstanceOf(env, binding, untionBinding)) {
\r
486 return getPythonUnionObject(env, value, binding);
\r
488 else if ((*env)->IsInstanceOf(env, binding, variantBinding)) {
\r
489 return getPythonVariantObject(env, value, binding);
\r
496 void setPythonVariable(PyObject *module, PyObject *name, PyObject *value) {
\r
497 if (name && value) {
\r
498 PyDict_SetItem(PyModule_GetDict(module), name, value);
\r
505 static npy_intp nContiguous(int d, int nd, npy_intp *strides, npy_intp *dims, npy_intp *ncont) {
\r
511 npy_intp n = nContiguous(d+1, nd, strides, dims, ncont);
\r
512 ncont[d] = n > 0 && strides[d] == sizeof(double) * n ? dims[d] * n : 0;
\r
517 static void copyDoubleArrayValues(JNIEnv *env, jdoubleArray array, double *data, npy_intp *offset, int d, int nd, npy_intp *strides, npy_intp *dims, npy_intp *ncont) {
\r
518 if (ncont[d] > 0) {
\r
519 (*env)->SetDoubleArrayRegion(env, array, (jint)*offset, (jint)ncont[d], data);
\r
520 *offset += ncont[d];
\r
524 for (i = 0; i < dims[d]; i++) {
\r
525 copyDoubleArrayValues(env, array, (double*)((char*)data + strides[d] * i), offset, d+1, nd, strides, dims, ncont);
\r
530 jobject pythonBoolAsBooleanObject(JNIEnv *env, PyObject *value) {
\r
531 jclass booleanClass = (*env)->FindClass(env, "java/lang/Boolean");
\r
532 jmethodID valueOfMethod = (*env)->GetStaticMethodID(env, booleanClass, "valueOf", "(Z)Ljava/lang/Boolean;");
\r
534 return (*env)->CallStaticObjectMethod(env, booleanClass, valueOfMethod, (jboolean)(value == Py_True));
\r
537 jobject pythonLongAsLongObject(JNIEnv *env, PyObject *value) {
\r
538 jclass longClass = (*env)->FindClass(env, "java/lang/Long");
\r
539 jmethodID valueOfMethod = (*env)->GetStaticMethodID(env, longClass, "valueOf", "(J)Ljava/lang/Long;");
\r
541 return (*env)->CallStaticObjectMethod(env, longClass, valueOfMethod, PyLong_AsLongLong(value));
\r
544 jobject pythonFloatAsDoubleObject(JNIEnv *env, PyObject *value) {
\r
545 jclass doubleClass = (*env)->FindClass(env, "java/lang/Double");
\r
546 jmethodID valueOfMethod = (*env)->GetStaticMethodID(env, doubleClass, "valueOf", "(D)Ljava/lang/Double;");
\r
548 return (*env)->CallStaticObjectMethod(env, doubleClass, valueOfMethod, PyFloat_AsDouble(value));
\r
551 jobject pythonByteArrayAsByteArray(JNIEnv *env, PyObject *value) {
\r
552 Py_ssize_t size = PyByteArray_Size(value);
\r
553 jbyteArray result = (*env)->NewByteArray(env, (jsize)size);
\r
554 char *bytes = PyByteArray_AsString(value);
\r
556 (*env)->SetByteArrayRegion(env, result, 0, size, bytes);
\r
561 jstring pythonStringAsJavaString(JNIEnv *env, PyObject *string) {
\r
562 PyObject *utf16Value = PyUnicode_AsUTF16String(string);
\r
563 Py_ssize_t len = PyBytes_Size(utf16Value) / 2;
\r
564 char *bytes = PyBytes_AsString(utf16Value);
\r
566 // Create Java string, skipping the byte order mark in the beginning
\r
567 jstring result = (*env)->NewString(env, (jchar *)bytes + 1, (jsize)min(len, JAVA_MAXINT) - 1);
\r
569 Py_XDECREF(utf16Value);
\r
574 jobjectArray pythonSequenceAsStringArray(JNIEnv *env, PyObject *seq) {
\r
575 Py_ssize_t len = PySequence_Size(seq);
\r
576 jsize jlen = (jsize)min(len, JAVA_MAXINT);
\r
577 jobjectArray array = (*env)->NewObjectArray(env, jlen, (*env)->FindClass(env, STRING_CLASS), NULL);
\r
581 for (i = 0; i < jlen; i++) {
\r
582 PyObject *item = PySequence_GetItem(seq, i);
\r
583 if (PyUnicode_Check(item)) {
\r
584 jstring value = pythonStringAsJavaString(env, item);
\r
585 (*env)->SetObjectArrayElement(env, array, i, value);
\r
588 throwPythonException(env, "List item not a string");
\r
596 jdoubleArray pythonSequenceAsDoubleArray(JNIEnv *env, PyObject *seq) {
\r
597 Py_ssize_t len = PySequence_Size(seq);
\r
598 jsize jlen = (jsize)min(len, JAVA_MAXINT);
\r
599 jdoubleArray array = (*env)->NewDoubleArray(env, jlen);
\r
603 for (i = 0; i < jlen; i++) {
\r
604 PyObject *item = PySequence_GetItem(seq, i);
\r
605 if (PyFloat_Check(item)) {
\r
606 double value = PyFloat_AsDouble(item);
\r
607 (*env)->SetDoubleArrayRegion(env, array, i, 1, &value);
\r
610 throwPythonException(env, "List item not a floating point value");
\r
618 jobject pythonObjectAsObject(JNIEnv *env, PyObject *value) {
\r
619 if (PyBool_Check(value))
\r
620 return pythonBoolAsBooleanObject(env, value);
\r
621 else if (PyLong_Check(value))
\r
622 return pythonLongAsLongObject(env, value);
\r
623 else if (PyFloat_Check(value))
\r
624 return pythonFloatAsDoubleObject(env, value);
\r
625 else if (PyUnicode_Check(value))
\r
626 return pythonStringAsJavaString(env, value);
\r
627 else if (PyByteArray_Check(value))
\r
628 return pythonByteArrayAsByteArray(env, value);
\r
629 else if (PyDict_Check(value))
\r
630 return pythonDictionaryAsMap(env, value);
\r
631 else if (hasNumpy && PyArray_Check(value))
\r
632 return pythonArrayAsNDArray(env, (PyArrayObject *)value);
\r
633 else if (PySequence_Check(value))
\r
634 return pythonSequenceAsObjectArray(env, value);
\r
639 jobjectArray pythonSequenceAsObjectArray(JNIEnv *env, PyObject *seq) {
\r
640 Py_ssize_t len = PySequence_Size(seq);
\r
641 jsize jlen = (jsize)min(len, JAVA_MAXINT);
\r
642 jobjectArray array = (*env)->NewObjectArray(env, jlen, (*env)->FindClass(env, OBJECT_CLASS), NULL);
\r
646 for (i = 0; i < jlen; i++) {
\r
647 PyObject *item = PySequence_GetItem(seq, i);
\r
648 jobject object = pythonObjectAsObject(env, item);
\r
649 (*env)->SetObjectArrayElement(env, array, i, object);
\r
655 jbooleanArray pythonSequenceAsBooleanArray(JNIEnv *env, PyObject *seq) {
\r
656 Py_ssize_t len = PySequence_Size(seq);
\r
657 jsize jlen = (jsize)min(len, JAVA_MAXINT);
\r
658 jbooleanArray array = (*env)->NewBooleanArray(env, jlen);
\r
662 for (i = 0; i < jlen; i++) {
\r
663 PyObject *item = PySequence_GetItem(seq, i);
\r
664 if (PyBool_Check(item)) {
\r
665 jboolean value = item == Py_True;
\r
666 (*env)->SetBooleanArrayRegion(env, array, i, 1, &value);
\r
669 throwPythonException(env, "List item not a boolean");
\r
677 jintArray pythonSequenceAsIntegerArray(JNIEnv *env, PyObject *seq) {
\r
678 Py_ssize_t len = PySequence_Size(seq);
\r
679 jsize jlen = (jsize)min(len, JAVA_MAXINT);
\r
680 jintArray array = (*env)->NewIntArray(env, jlen);
\r
684 for (i = 0; i < jlen; i++) {
\r
685 PyObject *item = PySequence_GetItem(seq, i);
\r
686 if (PyLong_Check(item)) {
\r
687 jint value = PyLong_AsLong(item);
\r
688 (*env)->SetIntArrayRegion(env, array, i, 1, &value);
\r
691 throwPythonException(env, "List item not an integer");
\r
699 jlongArray pythonSequenceAsLongArray(JNIEnv *env, PyObject *seq) {
\r
700 Py_ssize_t len = PySequence_Size(seq);
\r
701 jsize jlen = (jsize)min(len, JAVA_MAXINT);
\r
702 jlongArray array = (*env)->NewLongArray(env, jlen);
\r
706 for (i = 0; i < jlen; i++) {
\r
707 PyObject *item = PySequence_GetItem(seq, i);
\r
708 if (PyLong_Check(item)) {
\r
709 jlong value = PyLong_AsLongLong(item);
\r
710 (*env)->SetLongArrayRegion(env, array, i, 1, &value);
\r
713 throwPythonException(env, "List item not an integer");
\r
721 jobject pythonArrayAsNDArray(JNIEnv *env, PyArrayObject *array) {
\r
722 jclass ndarrayClass = (*env)->FindClass(env, NDARRAY_CLASS);
\r
723 jmethodID constructor = (*env)->GetMethodID(env, ndarrayClass, "<init>", "([I[D)V");
\r
725 int ndims = PyArray_NDIM(array);
\r
726 npy_intp *dims = PyArray_DIMS(array);
\r
728 npy_intp len = PyArray_Size((PyObject*)array);
\r
729 double *values = (double*)PyArray_DATA(array);
\r
731 jboolean isFortran = PyArray_ISFORTRAN(array) != 0;
\r
735 if (len > JAVA_MAXINT) {
\r
736 throwPythonException(env, "Array too large");
\r
741 jintArray jdims = (*env)->NewIntArray(env, ndims);
\r
742 jdoubleArray jvalues = (*env)->NewDoubleArray(env, (jsize)len);
\r
744 for (i = 0; i < ndims; i++) {
\r
745 jint dim = (jint)dims[i];
\r
746 (*env)->SetIntArrayRegion(env, jdims, i, 1, &dim);
\r
749 if (PyArray_IS_C_CONTIGUOUS(array)) {
\r
750 (*env)->SetDoubleArrayRegion(env, jvalues, 0, (jsize)len, values);
\r
753 npy_intp offset = 0;
\r
754 npy_intp *strides = PyArray_STRIDES(array);
\r
755 npy_intp *ncont = (npy_intp*)malloc((ndims + 1) * sizeof(npy_intp));
\r
756 nContiguous(0, ndims, strides, dims, ncont);
\r
757 copyDoubleArrayValues(env, jvalues, values, &offset, 0, ndims, strides, dims, ncont);
\r
761 return (*env)->NewObject(env, ndarrayClass, constructor, jdims, jvalues, isFortran);
\r
765 jobject pythonDictionaryAsMap(JNIEnv *env, PyObject *dict) {
\r
766 jclass hashmapClass = (*env)->FindClass(env, "java/util/HashMap");
\r
767 jmethodID constructor = (*env)->GetMethodID(env, hashmapClass, "<init>", "(I)V");
\r
768 jmethodID putMethod = (*env)->GetMethodID(env, hashmapClass, "put", "(L" OBJECT_CLASS ";L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");
\r
770 Py_ssize_t size = PyDict_Size(dict);
\r
771 jobject map = (*env)->NewObject(env, hashmapClass, constructor, (jint)size);
\r
773 PyObject *key, *value;
\r
774 Py_ssize_t pos = 0;
\r
776 while (PyDict_Next(dict, &pos, &key, &value)) {
\r
777 jobject keyObject = pythonObjectAsObject(env, key);
\r
778 jobject valueObject = pythonObjectAsObject(env, value);
\r
779 (*env)->CallObjectMethod(env, map, putMethod, keyObject, valueObject);
\r
785 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonBooleanVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jboolean value) {
\r
786 PyObject *module = (PyObject*)contextID;
\r
788 PyObject *pythonName = getPythonString(env, variableName);
\r
789 PyObject *val = getPythonBool(value);
\r
791 setPythonVariable(module, pythonName, val);
\r
794 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonBooleanArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jbooleanArray value) {
\r
795 PyObject *module = (PyObject*)contextID;
\r
797 PyObject *pythonName = getPythonString(env, variableName);
\r
798 PyObject *val = getPythonBooleanList(env, value);
\r
800 setPythonVariable(module, pythonName, val);
\r
803 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonLongVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jlong value) {
\r
804 PyObject *module = (PyObject*)contextID;
\r
806 PyObject *pythonName = getPythonString(env, variableName);
\r
807 PyObject *val = PyLong_FromLongLong(value);
\r
809 setPythonVariable(module, pythonName, val);
\r
812 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonIntegerArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jintArray value) {
\r
813 PyObject *module = (PyObject*)contextID;
\r
815 PyObject *pythonName = getPythonString(env, variableName);
\r
816 PyObject *val = getPythonIntegerList(env, value);
\r
818 setPythonVariable(module, pythonName, val);
\r
821 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonLongArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jlongArray value) {
\r
822 PyObject *module = (PyObject*)contextID;
\r
824 PyObject *pythonName = getPythonString(env, variableName);
\r
825 PyObject *val = getPythonLongList(env, value);
\r
827 setPythonVariable(module, pythonName, val);
\r
830 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonDoubleVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jdouble value) {
\r
831 PyObject *module = (PyObject*)contextID;
\r
833 PyObject *pythonName = getPythonString(env, variableName);
\r
834 PyObject *val = PyFloat_FromDouble(value);
\r
836 setPythonVariable(module, pythonName, val);
\r
839 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonFloatArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jfloatArray value) {
\r
840 PyObject *module = (PyObject*)contextID;
\r
842 PyObject *pythonName = getPythonString(env, variableName);
\r
843 PyObject *val = getPythonFloatList(env, value);
\r
845 setPythonVariable(module, pythonName, val);
\r
848 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonDoubleArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jdoubleArray value) {
\r
849 PyObject *module = (PyObject*)contextID;
\r
851 PyObject *pythonName = getPythonString(env, variableName);
\r
852 PyObject *val = getPythonDoubleList(env, value);
\r
854 setPythonVariable(module, pythonName, val);
\r
857 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonStringVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jstring value) {
\r
858 PyObject *module = (PyObject*)contextID;
\r
860 PyObject *pythonName = getPythonString(env, variableName);
\r
861 PyObject *val = getPythonString(env, value);
\r
863 setPythonVariable(module, pythonName, val);
\r
866 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonStringArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jobjectArray value) {
\r
867 PyObject *module = (PyObject*)contextID;
\r
869 PyObject *pythonName = getPythonString(env, variableName);
\r
870 PyObject *val = getPythonStringList(env, value);
\r
872 setPythonVariable(module, pythonName, val);
\r
875 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonNDArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jobject value) {
\r
876 PyObject *module = (PyObject*)contextID;
\r
879 throwPythonException(env, "Importing numpy failed");
\r
884 PyObject *pythonName = getPythonString(env, variableName);
\r
885 PyObject *val = getPythonNDArray(env, value);
\r
887 setPythonVariable(module, pythonName, val);
\r
891 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonVariantVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jobject value, jobject binding) {
\r
892 PyObject *module = (PyObject*)contextID;
\r
894 PyObject *pythonName = getPythonString(env, variableName);
\r
895 PyObject *val = getPythonObject(env, value, binding);
\r
897 setPythonVariable(module, pythonName, val);
\r
900 JNIEXPORT jint JNICALL Java_org_simantics_pythonlink_PythonContext_executePythonStatementImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring statement) {
\r
901 PyObject *module = (PyObject*)contextID;
\r
903 const char *utfchars = (*env)->GetStringUTFChars(env, statement, NULL);
\r
909 globals = PyModule_GetDict(module);
\r
912 PyObject *result = PyRun_String(utfchars, Py_file_input, globals, globals);
\r
914 PyObject *exceptionType = PyErr_Occurred();
\r
915 if (exceptionType != NULL) {
\r
916 PyObject *exception, *traceback;
\r
917 PyErr_Fetch(&exceptionType, &exception, &traceback);
\r
920 PyObject *tracebackModule = PyImport_ImportModule("traceback");
\r
921 if (tracebackModule != NULL) {
\r
922 PyObject *formatExc = PyDict_GetItemString(PyModule_GetDict(tracebackModule), "format_exception");
\r
923 if (formatExc != NULL) {
\r
924 PyObject *args = PyTuple_Pack(3, exceptionType, exception, traceback);
\r
925 PyObject *message = PyObject_CallObject(formatExc, args);
\r
926 if (message != NULL) {
\r
927 PyObject *emptyStr = PyUnicode_FromString("");
\r
928 PyObject *joined = PyUnicode_Join(emptyStr, message);
\r
929 char *messageStr = PyUnicode_AsUTF8(joined);
\r
930 throwPythonException(env, messageStr);
\r
932 Py_DECREF(emptyStr);
\r
933 Py_DECREF(message);
\r
936 throwPythonException(env, "Internal error, no message");
\r
939 Py_DECREF(formatExc);
\r
942 throwPythonException(env, "Internal error, no format_exc function");
\r
944 Py_DECREF(tracebackModule);
\r
947 throwPythonException(env, "Internal error, no traceback module");
\r
952 (*env)->ReleaseStringUTFChars(env, statement, utfchars);
\r
954 return result != NULL ? 0 : 1;
\r
959 JNIEXPORT jstring JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonStringVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
960 PyObject *module = (PyObject*)contextID;
\r
962 PyObject *pythonName = getPythonString(env, variableName);
\r
964 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
965 if (value == NULL) {
\r
966 throwPythonException(env, "Python variable not found");
\r
970 if (!PyUnicode_Check(value)) {
\r
971 throwPythonException(env, "Python variable not a string");
\r
976 jstring result = pythonStringAsJavaString(env, value);
\r
981 JNIEXPORT jobjectArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonStringArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
982 PyObject *module = (PyObject*)contextID;
\r
984 PyObject *pythonName = getPythonString(env, variableName);
\r
986 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
987 if (value == NULL) {
\r
988 throwPythonException(env, "Python variable not found");
\r
992 if (!PySequence_Check(value)) {
\r
993 throwPythonException(env, "Python variable not a sequence");
\r
998 jobjectArray result = pythonSequenceAsStringArray(env, value);
\r
1003 JNIEXPORT jboolean JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonBooleanVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1004 PyObject *module = (PyObject*)contextID;
\r
1006 PyObject *pythonName = getPythonString(env, variableName);
\r
1008 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1009 if (value == NULL) {
\r
1010 throwPythonException(env, "Python variable not found");
\r
1014 if (!PyBool_Check(value)) {
\r
1015 throwPythonException(env, "Python variable not a boolean");
\r
1019 return value == Py_True;
\r
1022 JNIEXPORT jbooleanArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonBooleanArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1023 PyObject *module = (PyObject*)contextID;
\r
1025 PyObject *pythonName = getPythonString(env, variableName);
\r
1027 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1028 if (value == NULL) {
\r
1029 throwPythonException(env, "Python variable not found");
\r
1033 if (!PySequence_Check(value)) {
\r
1034 throwPythonException(env, "Python variable not a sequence");
\r
1039 jbooleanArray result = pythonSequenceAsBooleanArray(env, value);
\r
1044 JNIEXPORT jlong JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonLongVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1045 PyObject *module = (PyObject*)contextID;
\r
1047 PyObject *pythonName = getPythonString(env, variableName);
\r
1049 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1050 if (value == NULL) {
\r
1051 throwPythonException(env, "Python variable not found");
\r
1055 if (!PyLong_Check(value)) {
\r
1056 throwPythonException(env, "Python variable not an integer");
\r
1061 jlong result = PyLong_AsLongLong(value);
\r
1066 JNIEXPORT jintArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonIntegerArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1067 PyObject *module = (PyObject*)contextID;
\r
1069 PyObject *pythonName = getPythonString(env, variableName);
\r
1071 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1072 if (value == NULL) {
\r
1073 throwPythonException(env, "Python variable not found");
\r
1077 if (!PySequence_Check(value)) {
\r
1078 throwPythonException(env, "Python variable not a sequence");
\r
1083 jintArray result = pythonSequenceAsIntegerArray(env, value);
\r
1088 JNIEXPORT jlongArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonLongArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1089 PyObject *module = (PyObject*)contextID;
\r
1091 PyObject *pythonName = getPythonString(env, variableName);
\r
1093 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1094 if (value == NULL) {
\r
1095 throwPythonException(env, "Python variable not found");
\r
1099 if (!PySequence_Check(value)) {
\r
1100 throwPythonException(env, "Python variable not a sequence");
\r
1105 jlongArray result = pythonSequenceAsLongArray(env, value);
\r
1110 JNIEXPORT jdouble JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonDoubleVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1111 PyObject *module = (PyObject*)contextID;
\r
1113 PyObject *pythonName = getPythonString(env, variableName);
\r
1115 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1116 if (value == NULL) {
\r
1117 throwPythonException(env, "Python variable not found");
\r
1121 if (!PyFloat_Check(value)) {
\r
1122 throwPythonException(env, "Python variable not a float");
\r
1127 jdouble result = PyFloat_AsDouble(value);
\r
1132 JNIEXPORT jdoubleArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonDoubleArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1133 PyObject *module = (PyObject*)contextID;
\r
1135 PyObject *pythonName = getPythonString(env, variableName);
\r
1137 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1138 if (value == NULL) {
\r
1139 throwPythonException(env, "Python variable not found");
\r
1143 if (!PySequence_Check(value)) {
\r
1144 throwPythonException(env, "Python variable not a sequence");
\r
1149 jdoubleArray result = pythonSequenceAsDoubleArray(env, value);
\r
1154 JNIEXPORT jobject JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonNDArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1155 PyObject *module = (PyObject*)contextID;
\r
1158 throwPythonException(env, "Importing numpy failed");
\r
1163 PyObject *pythonName = getPythonString(env, variableName);
\r
1165 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1166 if (value == NULL) {
\r
1167 throwPythonException(env, "Python variable not found");
\r
1171 if (!PyArray_Check(value)) {
\r
1172 throwPythonException(env, "Python variable not an ndarray");
\r
1176 if (PyArray_TYPE((PyArrayObject*)value) != NPY_DOUBLE) {
\r
1177 throwPythonException(env, "Only ndarrays of type double are supported");
\r
1182 jobject result = pythonArrayAsNDArray(env, (PyArrayObject *)value);
\r
1188 JNIEXPORT jobject JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariantVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1189 PyObject *module = (PyObject*)contextID;
\r
1191 PyObject *pythonName = getPythonString(env, variableName);
\r
1193 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1194 if (value == NULL) {
\r
1195 throwPythonException(env, "Python variable not found");
\r
1199 hasNumpy = _import_array() != -1;
\r
1202 jobject result = pythonObjectAsObject(env, value);
\r
1207 JNIEXPORT jint JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariableTypeImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1208 PyObject *module = (PyObject*)contextID;
\r
1209 PyObject *dict = PyModule_GetDict(module);
\r
1211 PyObject *pythonName = getPythonString(env, variableName);
\r
1213 if (!PyDict_Contains(dict, pythonName)) {
\r
1218 PyObject *value = PyDict_GetItem(dict, pythonName);
\r
1222 if (PyBool_Check(value))
\r
1224 else if (PyLong_Check(value))
\r
1226 else if (PyFloat_Check(value))
\r
1228 else if (PyUnicode_Check(value))
\r
1230 else if (PyByteArray_Check(value))
\r
1232 else if (PyDict_Check(value))
\r
1234 else if (hasNumpy && PyArray_Check(value))
\r
1236 else if (PySequence_Check(value))
\r
1245 JNIEXPORT jobjectArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariableNamesImpl(JNIEnv *env, jobject thisObj, jlong contextID) {
\r
1246 PyObject *module = (PyObject*)contextID;
\r
1247 PyObject *dict = PyModule_GetDict(module);
\r
1249 PyObject *keys = PyDict_Keys(dict);
\r
1250 Py_ssize_t size = PyList_Size(keys);
\r
1252 jobjectArray result = (*env)->NewObjectArray(env, (jsize)size, (*env)->FindClass(env, STRING_CLASS), NULL);
\r
1255 for (i = 0; i < size; i++) {
\r
1256 jstring javaName = pythonStringAsJavaString(env, PyList_GetItem(keys, i));
\r
1257 (*env)->SetObjectArrayElement(env, result, (jint)i, javaName);
\r
1265 BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
\r
1266 //extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
\r
1268 switch (fdwReason)
\r
1270 case DLL_PROCESS_ATTACH:
\r
1271 // attach to process
\r
1272 // return FALSE to fail DLL load
\r
1275 case DLL_PROCESS_DETACH:
\r
1276 // detach from process
\r
1279 case DLL_THREAD_ATTACH:
\r
1280 // attach to thread
\r
1283 case DLL_THREAD_DETACH:
\r
1284 // detach from thread
\r
1287 return TRUE; // succesful
\r