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 PyObject* getModule(jlong contextID) {
\r
36 return PyState_FindModule((PyModuleDef*) contextID);
\r
37 // return PyImport_AddModule("__main__");
\r
40 int moduleCount = 0;
\r
44 static JNIEnv *currentEnv = NULL;
\r
45 jobject sclWriter = NULL;
\r
48 writeToSCL(PyObject *self, PyObject *args)
\r
50 if (currentEnv != NULL && sclWriter != NULL) {
\r
51 JNIEnv *env = currentEnv;
\r
55 if (!PyArg_ParseTuple(args, "u#", &what, &length))
\r
59 jclass writerClass = (*env)->FindClass(env, WRITER_CLASS);
\r
60 jmethodID writeMethod = (*env)->GetMethodID(env, writerClass, "write", "([CII)V");
\r
61 jcharArray chars = (*env)->NewCharArray(env, (jsize)length);
\r
63 (*env)->SetCharArrayRegion(env, chars, 0, length, what);
\r
64 (*env)->CallVoidMethod(env, sclWriter, writeMethod, chars, 0, length);
\r
68 return Py_BuildValue("");
\r
71 static PyMethodDef sclWriterMethods[] = {
\r
72 {"write", writeToSCL, METH_VARARGS, "Write something."},
\r
73 {NULL, NULL, 0, NULL}
\r
77 JNIEXPORT jlong JNICALL Java_org_simantics_pythonlink_PythonContext_createContextImpl(JNIEnv *env, jobject thisObj) {
\r
85 static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "sclwriter", NULL, -1, sclWriterMethods, };
\r
86 PyObject *m = PyModule_Create(&moduledef);
\r
88 if (m == NULL) throwException(env, PYTHON_EXCEPTION, "Failed to create SCL writer module");
\r
89 PySys_SetObject("stdout", m);
\r
90 PySys_SetObject("stderr", m);
\r
93 hasNumpy = _import_array();
\r
94 hasNumpy = hasNumpy != -1;
\r
97 sprintf(name, "SCL_%d", ++moduleCount);
\r
101 PyModuleDef *modDef = malloc(sizeof(PyModuleDef));
\r
102 memset(modDef, 0, sizeof(PyModuleDef));
\r
103 modDef->m_name = strdup(name);
\r
104 modDef->m_doc = NULL;
\r
105 modDef->m_size = -1;
\r
107 module = PyModule_Create(modDef);
\r
109 PyState_AddModule(module, modDef);
\r
112 PyObject *builtin = PyImport_AddModule("builtins");
\r
113 PyObject *dict = PyModule_GetDict(module);
\r
114 PyDict_SetItemString(dict, "__builtin__", builtin);
\r
115 PyDict_SetItemString(dict, "__builtins__", builtin);
\r
117 return (jlong)modDef;
\r
122 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_deleteContextImpl(JNIEnv *env, jobject thisObj, jlong contextID) {
\r
123 PyModuleDef *modDef = (PyModuleDef*)contextID;
\r
124 PyObject *module = PyState_FindModule(modDef);
\r
125 Py_XDECREF(module);
\r
126 PyState_RemoveModule(modDef);
\r
127 free((char*)modDef->m_name);
\r
131 PyObject *getPythonBool(jboolean value) {
\r
140 PyObject *getPythonString(JNIEnv *env, jstring string) {
\r
141 jsize len = (*env)->GetStringLength(env, string);
\r
142 const jchar *chars = (*env)->GetStringChars(env, string, NULL);
\r
144 PyObject *value = PyUnicode_DecodeUTF16((char*)chars, 2*len, NULL, NULL);
\r
146 (*env)->ReleaseStringChars(env, string, chars);
\r
150 PyObject *getPythonStringList(JNIEnv *env, jobjectArray value) {
\r
151 jsize nitems = (*env)->GetArrayLength(env, value);
\r
152 jint *values = (*env)->GetIntArrayElements(env, value, NULL);
\r
153 jclass stringClass = (*env)->FindClass(env, STRING_CLASS);
\r
156 PyObject *result = PyList_New(nitems);
\r
157 for (i = 0; i < nitems; i++) {
\r
158 jobject item = (*env)->GetObjectArrayElement(env, value, i);
\r
159 if (item != NULL && (*env)->IsInstanceOf(env, item, stringClass)) {
\r
160 PyList_SetItem(result, i, getPythonString(env, (jstring)item));
\r
163 PyList_SetItem(result, i, Py_None);
\r
167 (*env)->ReleaseIntArrayElements(env, value, values, JNI_ABORT);
\r
171 PyObject *getPythonBooleanList(JNIEnv *env, jbooleanArray value) {
\r
172 jsize nitems = (*env)->GetArrayLength(env, value);
\r
173 jboolean *values = (*env)->GetBooleanArrayElements(env, value, NULL);
\r
176 PyObject *result = PyList_New(nitems);
\r
177 for (i = 0; i < nitems; i++) {
\r
178 PyList_SetItem(result, i, getPythonBool(values[i]));
\r
181 (*env)->ReleaseBooleanArrayElements(env, value, values, JNI_ABORT);
\r
185 PyObject *getPythonByteArray(JNIEnv *env, jbyteArray value) {
\r
186 jint len = (*env)->GetArrayLength(env, value);
\r
187 jbyte *values = (*env)->GetByteArrayElements(env, value, NULL);
\r
189 PyObject *result = PyByteArray_FromStringAndSize(values, len);
\r
191 (*env)->ReleaseByteArrayElements(env, value, values, JNI_ABORT);
\r
195 PyObject *getPythonIntegerList(JNIEnv *env, jintArray value) {
\r
196 jsize nitems = (*env)->GetArrayLength(env, value);
\r
197 jint *values = (*env)->GetIntArrayElements(env, value, NULL);
\r
200 PyObject *result = PyList_New(nitems);
\r
201 for (i = 0; i < nitems; i++) {
\r
202 PyList_SetItem(result, i, PyLong_FromLong(values[i]));
\r
205 (*env)->ReleaseIntArrayElements(env, value, values, JNI_ABORT);
\r
209 PyObject *getPythonLongList(JNIEnv *env, jlongArray value) {
\r
210 jsize nitems = (*env)->GetArrayLength(env, value);
\r
211 jlong *values = (*env)->GetLongArrayElements(env, value, NULL);
\r
214 PyObject *result = PyList_New(nitems);
\r
215 for (i = 0; i < nitems; i++) {
\r
216 PyList_SetItem(result, i, PyLong_FromLongLong(values[i]));
\r
219 (*env)->ReleaseLongArrayElements(env, value, values, JNI_ABORT);
\r
223 PyObject *getPythonFloatList(JNIEnv *env, jfloatArray value) {
\r
224 jsize nitems = (*env)->GetArrayLength(env, value);
\r
225 float *values = (*env)->GetFloatArrayElements(env, value, NULL);
\r
228 PyObject *result = PyList_New(nitems);
\r
229 for (i = 0; i < nitems; i++) {
\r
230 PyList_SetItem(result, i, PyFloat_FromDouble((double)values[i]));
\r
233 (*env)->ReleaseFloatArrayElements(env, value, values, JNI_ABORT);
\r
237 PyObject *getPythonDoubleList(JNIEnv *env, jdoubleArray value) {
\r
238 jsize nitems = (*env)->GetArrayLength(env, value);
\r
239 double *values = (*env)->GetDoubleArrayElements(env, value, NULL);
\r
242 PyObject *result = PyList_New(nitems);
\r
243 for (i = 0; i < nitems; i++) {
\r
244 PyList_SetItem(result, i, PyFloat_FromDouble(values[i]));
\r
247 (*env)->ReleaseDoubleArrayElements(env, value, values, JNI_ABORT);
\r
251 PyObject *getPythonNDArray(JNIEnv *env, jobject value) {
\r
252 jclass ndarrayClass = (*env)->FindClass(env, NDARRAY_CLASS);
\r
253 jmethodID dimsMethod = (*env)->GetMethodID(env, ndarrayClass, "dims", "()[I");
\r
254 jmethodID getValuesMethod = (*env)->GetMethodID(env, ndarrayClass, "getValues", "()[D");
\r
256 jintArray jdims = (*env)->CallObjectMethod(env, value, dimsMethod);
\r
257 jsize ndims = (*env)->GetArrayLength(env, jdims);
\r
258 jint *dims = (*env)->GetIntArrayElements(env, jdims, NULL);
\r
260 jdoubleArray jvalues = (*env)->CallObjectMethod(env, value, getValuesMethod);
\r
261 jsize len = (*env)->GetArrayLength(env, jvalues);
\r
262 jdouble *values = (*env)->GetDoubleArrayElements(env, jvalues, NULL);
\r
264 npy_intp *pyDims = (npy_intp*)malloc(ndims * sizeof(npy_intp));
\r
266 jint i, nelem = ndims > 0 ? 1 : 0;
\r
267 for (i = 0; i < ndims; i++) {
\r
269 pyDims[i] = dims[i];
\r
272 len = min(len, nelem);
\r
275 PyObject *array = PyArray_EMPTY(ndims, pyDims, NPY_DOUBLE, 0);
\r
276 double *data = (double *)PyArray_DATA((PyArrayObject*)array);
\r
278 memcpy(data, values, len * sizeof(double));
\r
282 (*env)->ReleaseDoubleArrayElements(env, jvalues, values, JNI_ABORT);
\r
283 (*env)->ReleaseIntArrayElements(env, jdims, dims, JNI_ABORT);
\r
289 PyObject *getPythonBooleanObject(JNIEnv *env, jobject object, jobject binding) {
\r
290 jclass bindingClass = (*env)->FindClass(env, BOOLEANBINDING_CLASS);
\r
291 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)Z");
\r
293 jboolean bvalue = (*env)->CallBooleanMethod(env, binding, getValueMethod, object);
\r
294 return getPythonBool(bvalue);
\r
297 PyObject *getPythonByteObject(JNIEnv *env, jobject object, jobject binding) {
\r
298 jclass bindingClass = (*env)->FindClass(env, BYTEBINDING_CLASS);
\r
299 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)B");
\r
301 jbyte v = (*env)->CallByteMethod(env, binding, getValueMethod, object);
\r
302 return PyLong_FromLong(v);
\r
305 PyObject *getPythonIntegerObject(JNIEnv *env, jobject object, jobject binding) {
\r
306 jclass bindingClass = (*env)->FindClass(env, INTEGERBINDING_CLASS);
\r
307 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)I");
\r
309 jint v = (*env)->CallIntMethod(env, binding, getValueMethod, object);
\r
310 return PyLong_FromLong(v);
\r
313 PyObject *getPythonLongObject(JNIEnv *env, jobject object, jobject binding) {
\r
314 jclass bindingClass = (*env)->FindClass(env, LONGBINDING_CLASS);
\r
315 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)J");
\r
317 jlong v = (*env)->CallLongMethod(env, binding, getValueMethod, object);
\r
318 return PyLong_FromLongLong(v);
\r
321 PyObject *getPythonFloatObject(JNIEnv *env, jobject object, jobject binding) {
\r
322 jclass bindingClass = (*env)->FindClass(env, FLOATBINDING_CLASS);
\r
323 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)F");
\r
325 jfloat v = (*env)->CallFloatMethod(env, binding, getValueMethod, object);
\r
326 return PyFloat_FromDouble(v);
\r
329 PyObject *getPythonDoubleObject(JNIEnv *env, jobject object, jobject binding) {
\r
330 jclass bindingClass = (*env)->FindClass(env, DOUBLEBINDING_CLASS);
\r
331 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)D");
\r
333 jdouble v = (*env)->CallDoubleMethod(env, binding, getValueMethod, object);
\r
334 return PyFloat_FromDouble(v);
\r
337 PyObject *getPythonStringObject(JNIEnv *env, jobject object, jobject binding) {
\r
338 jclass bindingClass = (*env)->FindClass(env, STRINGBINDING_CLASS);
\r
339 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue", "(L" OBJECT_CLASS ";)L" STRING_CLASS ";");
\r
341 jobject string = (*env)->CallObjectMethod(env, binding, getValueMethod, object);
\r
342 jsize len = (*env)->GetStringLength(env, string);
\r
343 const jchar *chars = (*env)->GetStringChars(env, string, NULL);
\r
345 PyObject *value = PyUnicode_DecodeUTF16((char*)chars, 2*len, NULL, NULL);
\r
347 (*env)->ReleaseStringChars(env, string, chars);
\r
351 PyObject *getPythonRecordObject(JNIEnv *env, jobject object, jobject binding) {
\r
352 jclass bindingClass = (*env)->FindClass(env, RECORDBINDING_CLASS);
\r
353 jmethodID typeMethod = (*env)->GetMethodID(env, bindingClass, "type", "()L" RECORDTYPE_CLASS ";");
\r
354 jmethodID getComponent = (*env)->GetMethodID(env, bindingClass, "getComponent", "(L" OBJECT_CLASS ";I)L" OBJECT_CLASS ";");
\r
355 jmethodID getComponentBinding = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "(I)L" BINDING_CLASS ";");
\r
357 jclass recordType = (*env)->FindClass(env, RECORDTYPE_CLASS);
\r
358 jmethodID getTypeComponent = (*env)->GetMethodID(env, recordType, "getComponent", "(I)L" COMPONENT_CLASS ";");
\r
359 jmethodID getComponentCount = (*env)->GetMethodID(env, recordType, "getComponentCount", "()I");
\r
361 jclass componentClass = (*env)->FindClass(env, COMPONENT_CLASS);
\r
362 jfieldID nameField = (*env)->GetFieldID(env, componentClass, "name", "L" STRING_CLASS ";");
\r
364 jobject type = (*env)->CallObjectMethod(env, binding, typeMethod);
\r
365 jint n = (*env)->CallIntMethod(env, type, getComponentCount);
\r
368 PyObject *result = PyDict_New();
\r
369 for (i = 0; i < n; i++) {
\r
370 jobject recordTypeComponent = (*env)->CallObjectMethod(env, type, getComponent, i);
\r
371 jstring fieldName = (jstring)(*env)->GetObjectField(env, recordTypeComponent, nameField);
\r
372 jobject componentObject = (*env)->CallObjectMethod(env, binding, getComponent, object, i);
\r
373 jobject componentBinding = (*env)->CallObjectMethod(env, binding, getComponentBinding, i);
\r
375 PyObject *item = getPythonObject(env, componentObject, componentBinding);
\r
376 PyDict_SetItem(result, getPythonString(env, fieldName), item);
\r
382 PyObject *getPythonArrayObject(JNIEnv *env, jobject object, jobject binding) {
\r
383 jclass bindingClass = (*env)->FindClass(env, ARRAYBINDING_CLASS);
\r
384 jmethodID componentBindingMethod = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "()L" BINDING_CLASS ";");
\r
385 jmethodID sizeMethod = (*env)->GetMethodID(env, bindingClass, "size", "(L" OBJECT_CLASS ";)I");
\r
386 jmethodID getMethod = (*env)->GetMethodID(env, bindingClass, "get", "(L" OBJECT_CLASS ";I)L" OBJECT_CLASS ";");
\r
388 jobject componentBinding = (*env)->CallObjectMethod(env, binding, componentBindingMethod);
\r
390 jint size = (*env)->CallIntMethod(env, binding, sizeMethod, object);
\r
392 PyObject *result = PyList_New(size);
\r
395 for (i = 0; i < size; i++) {
\r
396 jobject item = (*env)->CallObjectMethod(env, binding, getMethod, object, i);
\r
398 PyList_SetItem(result, i, getPythonObject(env, item, componentBinding));
\r
400 PyList_SetItem(result, i, Py_None);
\r
406 PyObject *getPythonMapObject(JNIEnv *env, jobject object, jobject binding) {
\r
407 jclass objectClass = (*env)->FindClass(env, OBJECT_CLASS);
\r
408 jclass bindingClass = (*env)->FindClass(env, MAPBINDING_CLASS);
\r
409 jmethodID getKeyBindingMethod = (*env)->GetMethodID(env, bindingClass, "getKeyBinding", "()L" BINDING_CLASS ";");
\r
410 jmethodID getValueBindingMethod = (*env)->GetMethodID(env, bindingClass, "getValueBinding", "()L" BINDING_CLASS ";");
\r
411 jmethodID sizeMethod = (*env)->GetMethodID(env, bindingClass, "size", "(L" OBJECT_CLASS ";)I");
\r
412 jmethodID getAllMethod = (*env)->GetMethodID(env, bindingClass, "getAll", "(L" OBJECT_CLASS ";[L" OBJECT_CLASS ";[L" OBJECT_CLASS ";)V");
\r
414 jobject keyBinding = (*env)->CallObjectMethod(env, binding, getKeyBindingMethod);
\r
415 jobject valueBinding = (*env)->CallObjectMethod(env, binding, getValueBindingMethod);
\r
417 jint size = (*env)->CallIntMethod(env, binding, sizeMethod, object);
\r
418 jobjectArray keys = (*env)->NewObjectArray(env, size, objectClass, NULL);
\r
419 jobjectArray values = (*env)->NewObjectArray(env, size, objectClass, NULL);
\r
421 PyObject *result = PyDict_New();
\r
424 (*env)->CallVoidMethod(env, binding, getAllMethod, object, keys, values);
\r
426 for (i = 0; i < size; i++) {
\r
427 jobject key = (*env)->GetObjectArrayElement(env, keys, i);
\r
428 jobject item = (*env)->GetObjectArrayElement(env, values, i);
\r
429 PyDict_SetItem(result, getPythonObject(env, key, keyBinding), getPythonObject(env, item, valueBinding));
\r
432 (*env)->DeleteLocalRef(env, keys);
\r
433 (*env)->DeleteLocalRef(env, values);
\r
438 PyObject *getPythonOptionalObject(JNIEnv *env, jobject object, jobject binding) {
\r
439 jclass bindingClass = (*env)->FindClass(env, OPTIONALBINDING_CLASS);
\r
440 jmethodID hasValueMethod = (*env)->GetMethodID(env, bindingClass, "hasValue", "(L" OBJECT_CLASS ";)Z");
\r
442 jboolean hasValue = (*env)->CallBooleanMethod(env, binding, hasValueMethod, object);
\r
445 jmethodID componentBindingMethod = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "()L" BINDING_CLASS ";");
\r
446 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "hasValue", "(L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");
\r
448 jobject componentBinding = (*env)->CallObjectMethod(env, binding, componentBindingMethod);
\r
449 jobject value = (*env)->CallObjectMethod(env, binding, getValueMethod, object);
\r
451 return getPythonObject(env, value, componentBinding);
\r
458 PyObject *getPythonUnionObject(JNIEnv *env, jobject object, jobject binding) {
\r
459 jclass bindingClass = (*env)->FindClass(env, UNIONBINDING_CLASS);
\r
460 jmethodID typeMethod = (*env)->GetMethodID(env, bindingClass, "type", "()L" RECORDTYPE_CLASS ";");
\r
461 jmethodID getTagMethod = (*env)->GetMethodID(env, bindingClass, "getTag", "(L" OBJECT_CLASS ";)I");
\r
462 jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue", "(L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");
\r
463 jmethodID getComponentBinding = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "(I)L" BINDING_CLASS ";");
\r
465 jclass unionType = (*env)->FindClass(env, UNIONTYPE_CLASS);
\r
466 jmethodID getTypeComponent = (*env)->GetMethodID(env, unionType, "getComponent", "(I)L" COMPONENT_CLASS ";");
\r
468 jclass componentClass = (*env)->FindClass(env, COMPONENT_CLASS);
\r
469 jfieldID nameField = (*env)->GetFieldID(env, componentClass, "name", "L" STRING_CLASS ";");
\r
471 jint tag = (*env)->CallIntMethod(env, binding, getTagMethod, object);
\r
472 jobject value = (*env)->CallObjectMethod(env, binding, getValueMethod, object);
\r
474 jobject type = (*env)->CallObjectMethod(env, binding, typeMethod);
\r
475 jobject typeComponent = (*env)->CallObjectMethod(env, type, getTypeComponent, tag);
\r
476 jstring compName = (*env)->GetObjectField(env, typeComponent, nameField);
\r
478 jobject componentBinding = (*env)->CallObjectMethod(env, binding, getComponentBinding, tag);
\r
480 PyObject *result = PyTuple_New(2);
\r
481 PyTuple_SetItem(result, 0, getPythonString(env, compName));
\r
482 PyTuple_SetItem(result, 1, getPythonObject(env, value, componentBinding));
\r
487 PyObject *getPythonVariantObject(JNIEnv *env, jobject object, jobject binding) {
\r
488 jclass bindingClass = (*env)->FindClass(env, VARIANTBINDING_CLASS);
\r
489 jmethodID getContentMethod = (*env)->GetMethodID(env, bindingClass, "getContent", "(L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");
\r
490 jmethodID getContentBindingMethod = (*env)->GetMethodID(env, bindingClass, "getContentBinding", "(L" OBJECT_CLASS ";)L" BINDING_CLASS ";");
\r
492 jobject content = (*env)->CallObjectMethod(env, binding, getContentMethod, object);
\r
493 jobject contentBinding = (*env)->CallObjectMethod(env, binding, getContentBindingMethod, object);
\r
495 return getPythonObject(env, content, contentBinding);
\r
498 PyObject *getPythonObject(JNIEnv *env, jobject value, jobject binding) {
\r
499 jclass booleanBinding = (*env)->FindClass(env, BOOLEANBINDING_CLASS);
\r
500 jclass byteBinding = (*env)->FindClass(env, BYTEBINDING_CLASS);
\r
501 jclass integerBinding = (*env)->FindClass(env, INTEGERBINDING_CLASS);
\r
502 jclass longBinding = (*env)->FindClass(env, LONGBINDING_CLASS);
\r
503 jclass floatBinding = (*env)->FindClass(env, FLOATBINDING_CLASS);
\r
504 jclass doubleBinding = (*env)->FindClass(env, DOUBLEBINDING_CLASS);
\r
505 jclass stringBinding = (*env)->FindClass(env, STRINGBINDING_CLASS);
\r
506 jclass recordBinding = (*env)->FindClass(env, RECORDBINDING_CLASS);
\r
507 jclass arrayBinding = (*env)->FindClass(env, ARRAYBINDING_CLASS);
\r
508 jclass mapBinding = (*env)->FindClass(env, MAPBINDING_CLASS);
\r
509 jclass optionalBinding = (*env)->FindClass(env, OPTIONALBINDING_CLASS);
\r
510 jclass untionBinding = (*env)->FindClass(env, UNIONBINDING_CLASS);
\r
511 jclass variantBinding = (*env)->FindClass(env, VARIANTBINDING_CLASS);
\r
516 if ((*env)->IsInstanceOf(env, binding, booleanBinding)) {
\r
517 return getPythonBooleanObject(env, value, binding);
\r
519 else if ((*env)->IsInstanceOf(env, binding, byteBinding)) {
\r
520 return getPythonByteObject(env, value, binding);
\r
522 else if ((*env)->IsInstanceOf(env, binding, integerBinding)) {
\r
523 return getPythonIntegerObject(env, value, binding);
\r
525 else if ((*env)->IsInstanceOf(env, binding, longBinding)) {
\r
526 return getPythonLongObject(env, value, binding);
\r
528 else if ((*env)->IsInstanceOf(env, binding, floatBinding)) {
\r
529 return getPythonFloatObject(env, value, binding);
\r
531 else if ((*env)->IsInstanceOf(env, binding, doubleBinding)) {
\r
532 return getPythonDoubleObject(env, value, binding);
\r
534 else if ((*env)->IsInstanceOf(env, binding, stringBinding)) {
\r
535 return getPythonStringObject(env, value, binding);
\r
537 else if ((*env)->IsInstanceOf(env, binding, recordBinding)) {
\r
538 return getPythonRecordObject(env, value, binding);
\r
540 else if ((*env)->IsInstanceOf(env, binding, arrayBinding)) {
\r
541 return getPythonArrayObject(env, value, binding);
\r
543 else if ((*env)->IsInstanceOf(env, binding, mapBinding)) {
\r
544 return getPythonMapObject(env, value, binding);
\r
546 else if ((*env)->IsInstanceOf(env, binding, optionalBinding)) {
\r
547 return getPythonOptionalObject(env, value, binding);
\r
549 else if ((*env)->IsInstanceOf(env, binding, untionBinding)) {
\r
550 return getPythonUnionObject(env, value, binding);
\r
552 else if ((*env)->IsInstanceOf(env, binding, variantBinding)) {
\r
553 return getPythonVariantObject(env, value, binding);
\r
560 void setPythonVariable(PyObject *module, PyObject *name, PyObject *value) {
\r
561 if (name && value) {
\r
562 PyDict_SetItem(PyModule_GetDict(module), name, value);
\r
569 static npy_intp nContiguous(int d, int nd, npy_intp *strides, npy_intp *dims, npy_intp *ncont) {
\r
575 npy_intp n = nContiguous(d+1, nd, strides, dims, ncont);
\r
576 ncont[d] = n > 0 && strides[d] == sizeof(double) * n ? dims[d] * n : 0;
\r
581 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
582 if (ncont[d] > 0) {
\r
583 (*env)->SetDoubleArrayRegion(env, array, (jint)*offset, (jint)ncont[d], data);
\r
584 *offset += ncont[d];
\r
588 for (i = 0; i < dims[d]; i++) {
\r
589 copyDoubleArrayValues(env, array, (double*)((char*)data + strides[d] * i), offset, d+1, nd, strides, dims, ncont);
\r
594 jobject pythonBoolAsBooleanObject(JNIEnv *env, PyObject *value) {
\r
595 jclass booleanClass = (*env)->FindClass(env, "java/lang/Boolean");
\r
596 jmethodID valueOfMethod = (*env)->GetStaticMethodID(env, booleanClass, "valueOf", "(Z)Ljava/lang/Boolean;");
\r
598 return (*env)->CallStaticObjectMethod(env, booleanClass, valueOfMethod, (jboolean)(value == Py_True));
\r
601 jobject pythonLongAsLongObject(JNIEnv *env, PyObject *value) {
\r
602 jclass longClass = (*env)->FindClass(env, "java/lang/Long");
\r
603 jmethodID valueOfMethod = (*env)->GetStaticMethodID(env, longClass, "valueOf", "(J)Ljava/lang/Long;");
\r
605 return (*env)->CallStaticObjectMethod(env, longClass, valueOfMethod, PyLong_AsLongLong(value));
\r
608 jobject pythonFloatAsDoubleObject(JNIEnv *env, PyObject *value) {
\r
609 jclass doubleClass = (*env)->FindClass(env, "java/lang/Double");
\r
610 jmethodID valueOfMethod = (*env)->GetStaticMethodID(env, doubleClass, "valueOf", "(D)Ljava/lang/Double;");
\r
612 return (*env)->CallStaticObjectMethod(env, doubleClass, valueOfMethod, PyFloat_AsDouble(value));
\r
615 jobject pythonByteArrayAsByteArray(JNIEnv *env, PyObject *value) {
\r
616 Py_ssize_t size = PyByteArray_Size(value);
\r
617 jbyteArray result = (*env)->NewByteArray(env, (jsize)size);
\r
618 char *bytes = PyByteArray_AsString(value);
\r
620 (*env)->SetByteArrayRegion(env, result, 0, size, bytes);
\r
625 jstring pythonStringAsJavaString(JNIEnv *env, PyObject *string) {
\r
626 PyObject *utf16Value = PyUnicode_AsUTF16String(string);
\r
627 Py_ssize_t len = PyBytes_Size(utf16Value) / 2;
\r
628 char *bytes = PyBytes_AsString(utf16Value);
\r
630 // Create Java string, skipping the byte order mark in the beginning
\r
631 jstring result = (*env)->NewString(env, (jchar *)bytes + 1, (jsize)min(len, JAVA_MAXINT) - 1);
\r
633 Py_XDECREF(utf16Value);
\r
638 jobjectArray pythonSequenceAsStringArray(JNIEnv *env, PyObject *seq) {
\r
639 Py_ssize_t len = PySequence_Size(seq);
\r
640 jsize jlen = (jsize)min(len, JAVA_MAXINT);
\r
641 jobjectArray array = (*env)->NewObjectArray(env, jlen, (*env)->FindClass(env, STRING_CLASS), NULL);
\r
645 for (i = 0; i < jlen; i++) {
\r
646 PyObject *item = PySequence_GetItem(seq, i);
\r
647 if (PyUnicode_Check(item)) {
\r
648 jstring value = pythonStringAsJavaString(env, item);
\r
649 (*env)->SetObjectArrayElement(env, array, i, value);
\r
652 throwPythonException(env, "List item not a string");
\r
660 jdoubleArray pythonSequenceAsDoubleArray(JNIEnv *env, PyObject *seq) {
\r
661 Py_ssize_t len = PySequence_Size(seq);
\r
662 jsize jlen = (jsize)min(len, JAVA_MAXINT);
\r
663 jdoubleArray array = (*env)->NewDoubleArray(env, jlen);
\r
667 for (i = 0; i < jlen; i++) {
\r
668 PyObject *item = PySequence_GetItem(seq, i);
\r
669 if (PyFloat_Check(item)) {
\r
670 double value = PyFloat_AsDouble(item);
\r
671 (*env)->SetDoubleArrayRegion(env, array, i, 1, &value);
\r
674 throwPythonException(env, "List item not a floating point value");
\r
682 jobject pythonObjectAsObject(JNIEnv *env, PyObject *value) {
\r
683 if (PyBool_Check(value))
\r
684 return pythonBoolAsBooleanObject(env, value);
\r
685 else if (PyLong_Check(value))
\r
686 return pythonLongAsLongObject(env, value);
\r
687 else if (PyFloat_Check(value))
\r
688 return pythonFloatAsDoubleObject(env, value);
\r
689 else if (PyUnicode_Check(value))
\r
690 return pythonStringAsJavaString(env, value);
\r
691 else if (PyByteArray_Check(value))
\r
692 return pythonByteArrayAsByteArray(env, value);
\r
693 else if (PyDict_Check(value))
\r
694 return pythonDictionaryAsMap(env, value);
\r
695 else if (hasNumpy && PyArray_Check(value))
\r
696 return pythonArrayAsNDArray(env, (PyArrayObject *)value);
\r
697 else if (PySequence_Check(value))
\r
698 return pythonSequenceAsObjectArray(env, value);
\r
703 jobjectArray pythonSequenceAsObjectArray(JNIEnv *env, PyObject *seq) {
\r
704 Py_ssize_t len = PySequence_Size(seq);
\r
705 jsize jlen = (jsize)min(len, JAVA_MAXINT);
\r
706 jobjectArray array = (*env)->NewObjectArray(env, jlen, (*env)->FindClass(env, OBJECT_CLASS), NULL);
\r
710 for (i = 0; i < jlen; i++) {
\r
711 PyObject *item = PySequence_GetItem(seq, i);
\r
712 jobject object = pythonObjectAsObject(env, item);
\r
713 (*env)->SetObjectArrayElement(env, array, i, object);
\r
719 jbooleanArray pythonSequenceAsBooleanArray(JNIEnv *env, PyObject *seq) {
\r
720 Py_ssize_t len = PySequence_Size(seq);
\r
721 jsize jlen = (jsize)min(len, JAVA_MAXINT);
\r
722 jbooleanArray array = (*env)->NewBooleanArray(env, jlen);
\r
726 for (i = 0; i < jlen; i++) {
\r
727 PyObject *item = PySequence_GetItem(seq, i);
\r
728 if (PyBool_Check(item)) {
\r
729 jboolean value = item == Py_True;
\r
730 (*env)->SetBooleanArrayRegion(env, array, i, 1, &value);
\r
733 throwPythonException(env, "List item not a boolean");
\r
741 jintArray pythonSequenceAsIntegerArray(JNIEnv *env, PyObject *seq) {
\r
742 Py_ssize_t len = PySequence_Size(seq);
\r
743 jsize jlen = (jsize)min(len, JAVA_MAXINT);
\r
744 jintArray array = (*env)->NewIntArray(env, jlen);
\r
748 for (i = 0; i < jlen; i++) {
\r
749 PyObject *item = PySequence_GetItem(seq, i);
\r
750 if (PyLong_Check(item)) {
\r
751 jint value = PyLong_AsLong(item);
\r
752 (*env)->SetIntArrayRegion(env, array, i, 1, &value);
\r
755 throwPythonException(env, "List item not an integer");
\r
763 jlongArray pythonSequenceAsLongArray(JNIEnv *env, PyObject *seq) {
\r
764 Py_ssize_t len = PySequence_Size(seq);
\r
765 jsize jlen = (jsize)min(len, JAVA_MAXINT);
\r
766 jlongArray array = (*env)->NewLongArray(env, jlen);
\r
770 for (i = 0; i < jlen; i++) {
\r
771 PyObject *item = PySequence_GetItem(seq, i);
\r
772 if (PyLong_Check(item)) {
\r
773 jlong value = PyLong_AsLongLong(item);
\r
774 (*env)->SetLongArrayRegion(env, array, i, 1, &value);
\r
777 throwPythonException(env, "List item not an integer");
\r
785 jobject pythonArrayAsNDArray(JNIEnv *env, PyArrayObject *array) {
\r
786 jclass ndarrayClass = (*env)->FindClass(env, NDARRAY_CLASS);
\r
787 jmethodID constructor = (*env)->GetMethodID(env, ndarrayClass, "<init>", "([I[D)V");
\r
789 int ndims = PyArray_NDIM(array);
\r
790 npy_intp *dims = PyArray_DIMS(array);
\r
792 npy_intp len = PyArray_Size((PyObject*)array);
\r
793 double *values = (double*)PyArray_DATA(array);
\r
795 jboolean isFortran = PyArray_ISFORTRAN(array) != 0;
\r
799 if (len > JAVA_MAXINT) {
\r
800 throwPythonException(env, "Array too large");
\r
805 jintArray jdims = (*env)->NewIntArray(env, ndims);
\r
806 jdoubleArray jvalues = (*env)->NewDoubleArray(env, (jsize)len);
\r
808 for (i = 0; i < ndims; i++) {
\r
809 jint dim = (jint)dims[i];
\r
810 (*env)->SetIntArrayRegion(env, jdims, i, 1, &dim);
\r
813 if (PyArray_IS_C_CONTIGUOUS(array)) {
\r
814 (*env)->SetDoubleArrayRegion(env, jvalues, 0, (jsize)len, values);
\r
817 npy_intp offset = 0;
\r
818 npy_intp *strides = PyArray_STRIDES(array);
\r
819 npy_intp *ncont = (npy_intp*)malloc((ndims + 1) * sizeof(npy_intp));
\r
820 nContiguous(0, ndims, strides, dims, ncont);
\r
821 copyDoubleArrayValues(env, jvalues, values, &offset, 0, ndims, strides, dims, ncont);
\r
825 return (*env)->NewObject(env, ndarrayClass, constructor, jdims, jvalues, isFortran);
\r
829 jobject pythonDictionaryAsMap(JNIEnv *env, PyObject *dict) {
\r
830 jclass hashmapClass = (*env)->FindClass(env, "java/util/HashMap");
\r
831 jmethodID constructor = (*env)->GetMethodID(env, hashmapClass, "<init>", "(I)V");
\r
832 jmethodID putMethod = (*env)->GetMethodID(env, hashmapClass, "put", "(L" OBJECT_CLASS ";L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");
\r
834 Py_ssize_t size = PyDict_Size(dict);
\r
835 jobject map = (*env)->NewObject(env, hashmapClass, constructor, (jint)size);
\r
837 PyObject *key, *value;
\r
838 Py_ssize_t pos = 0;
\r
840 while (PyDict_Next(dict, &pos, &key, &value)) {
\r
841 jobject keyObject = pythonObjectAsObject(env, key);
\r
842 jobject valueObject = pythonObjectAsObject(env, value);
\r
843 (*env)->CallObjectMethod(env, map, putMethod, keyObject, valueObject);
\r
849 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonBooleanVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jboolean value) {
\r
850 PyObject *module = getModule(contextID);
\r
852 PyObject *pythonName = getPythonString(env, variableName);
\r
853 PyObject *val = getPythonBool(value);
\r
855 setPythonVariable(module, pythonName, val);
\r
858 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonBooleanArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jbooleanArray value) {
\r
859 PyObject *module = getModule(contextID);
\r
861 PyObject *pythonName = getPythonString(env, variableName);
\r
862 PyObject *val = getPythonBooleanList(env, value);
\r
864 setPythonVariable(module, pythonName, val);
\r
867 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonLongVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jlong value) {
\r
868 PyObject *module = getModule(contextID);
\r
870 PyObject *pythonName = getPythonString(env, variableName);
\r
871 PyObject *val = PyLong_FromLongLong(value);
\r
873 setPythonVariable(module, pythonName, val);
\r
876 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonIntegerArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jintArray value) {
\r
877 PyObject *module = getModule(contextID);
\r
879 PyObject *pythonName = getPythonString(env, variableName);
\r
880 PyObject *val = getPythonIntegerList(env, value);
\r
882 setPythonVariable(module, pythonName, val);
\r
885 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonLongArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jlongArray value) {
\r
886 PyObject *module = getModule(contextID);
\r
888 PyObject *pythonName = getPythonString(env, variableName);
\r
889 PyObject *val = getPythonLongList(env, value);
\r
891 setPythonVariable(module, pythonName, val);
\r
894 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonDoubleVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jdouble value) {
\r
895 PyObject *module = getModule(contextID);
\r
897 PyObject *pythonName = getPythonString(env, variableName);
\r
898 PyObject *val = PyFloat_FromDouble(value);
\r
900 setPythonVariable(module, pythonName, val);
\r
903 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonFloatArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jfloatArray value) {
\r
904 PyObject *module = getModule(contextID);
\r
906 PyObject *pythonName = getPythonString(env, variableName);
\r
907 PyObject *val = getPythonFloatList(env, value);
\r
909 setPythonVariable(module, pythonName, val);
\r
912 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonDoubleArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jdoubleArray value) {
\r
913 PyObject *module = getModule(contextID);
\r
915 PyObject *pythonName = getPythonString(env, variableName);
\r
916 PyObject *val = getPythonDoubleList(env, value);
\r
918 setPythonVariable(module, pythonName, val);
\r
921 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonStringVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jstring value) {
\r
922 PyObject *module = getModule(contextID);
\r
924 PyObject *pythonName = getPythonString(env, variableName);
\r
925 PyObject *val = getPythonString(env, value);
\r
927 setPythonVariable(module, pythonName, val);
\r
930 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonStringArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jobjectArray value) {
\r
931 PyObject *module = getModule(contextID);
\r
933 PyObject *pythonName = getPythonString(env, variableName);
\r
934 PyObject *val = getPythonStringList(env, value);
\r
936 setPythonVariable(module, pythonName, val);
\r
939 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonNDArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jobject value) {
\r
940 PyObject *module = getModule(contextID);
\r
943 throwPythonException(env, "Importing numpy failed");
\r
948 PyObject *pythonName = getPythonString(env, variableName);
\r
949 PyObject *val = getPythonNDArray(env, value);
\r
951 setPythonVariable(module, pythonName, val);
\r
955 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonVariantVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jobject value, jobject binding) {
\r
956 PyObject *module = getModule(contextID);
\r
958 PyObject *pythonName = getPythonString(env, variableName);
\r
959 PyObject *val = getPythonObject(env, value, binding);
\r
961 setPythonVariable(module, pythonName, val);
\r
964 JNIEXPORT jint JNICALL Java_org_simantics_pythonlink_PythonContext_executePythonStatementImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring statement) {
\r
965 PyObject *module = getModule(contextID);
\r
967 const char *utfchars = (*env)->GetStringUTFChars(env, statement, NULL);
\r
971 jclass sclReportingWriterClass = (*env)->FindClass(env, SCL_REPORTING_WRITER_CLASS);
\r
972 jmethodID constructor = (*env)->GetMethodID(env, sclReportingWriterClass, "<init>", "()V");
\r
973 jmethodID flushMethod = (*env)->GetMethodID(env, sclReportingWriterClass, "flush", "()V");
\r
977 globals = PyModule_GetDict(module);
\r
980 if (sclReportingWriterClass && constructor)
\r
981 sclWriter = (*env)->NewObject(env, sclReportingWriterClass, constructor);
\r
986 PyObject *result = PyRun_String(utfchars, Py_file_input, globals, globals);
\r
988 PyObject *exceptionType = PyErr_Occurred();
\r
989 if (exceptionType != NULL) {
\r
990 PyObject *exception, *traceback;
\r
991 PyErr_Fetch(&exceptionType, &exception, &traceback);
\r
994 PyObject *tracebackModule = PyImport_ImportModule("traceback");
\r
995 if (tracebackModule != NULL) {
\r
996 PyObject *formatExc = PyDict_GetItemString(PyModule_GetDict(tracebackModule), "format_exception");
\r
997 if (formatExc != NULL) {
\r
998 PyObject *args = PyTuple_Pack(3, exceptionType, exception, traceback);
\r
999 PyObject *message = PyObject_CallObject(formatExc, args);
\r
1000 if (message != NULL) {
\r
1001 PyObject *emptyStr = PyUnicode_FromString("");
\r
1002 PyObject *joined = PyUnicode_Join(emptyStr, message);
\r
1003 char *messageStr = PyUnicode_AsUTF8(joined);
\r
1004 throwPythonException(env, messageStr);
\r
1005 Py_DECREF(joined);
\r
1006 Py_DECREF(emptyStr);
\r
1007 Py_DECREF(message);
\r
1010 throwPythonException(env, "Internal error, no message");
\r
1013 Py_DECREF(formatExc);
\r
1016 throwPythonException(env, "Internal error, no format_exc function");
\r
1018 Py_DECREF(tracebackModule);
\r
1021 throwPythonException(env, "Internal error, no traceback module");
\r
1026 (*env)->ReleaseStringUTFChars(env, statement, utfchars);
\r
1028 if (sclWriter != NULL) {
\r
1029 (*env)->CallVoidMethod(env, sclWriter, flushMethod);
\r
1032 currentEnv = NULL;
\r
1035 return result != NULL ? 0 : 1;
\r
1040 JNIEXPORT jstring JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonStringVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1041 PyObject *module = getModule(contextID);
\r
1043 PyObject *pythonName = getPythonString(env, variableName);
\r
1045 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1046 if (value == NULL) {
\r
1047 throwPythonException(env, "Python variable not found");
\r
1051 if (!PyUnicode_Check(value)) {
\r
1052 throwPythonException(env, "Python variable not a string");
\r
1057 jstring result = pythonStringAsJavaString(env, value);
\r
1062 JNIEXPORT jobjectArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonStringArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1063 PyObject *module = getModule(contextID);
\r
1065 PyObject *pythonName = getPythonString(env, variableName);
\r
1067 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1068 if (value == NULL) {
\r
1069 throwPythonException(env, "Python variable not found");
\r
1073 if (!PySequence_Check(value)) {
\r
1074 throwPythonException(env, "Python variable not a sequence");
\r
1079 jobjectArray result = pythonSequenceAsStringArray(env, value);
\r
1084 JNIEXPORT jboolean JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonBooleanVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1085 PyObject *module = getModule(contextID);
\r
1087 PyObject *pythonName = getPythonString(env, variableName);
\r
1089 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1090 if (value == NULL) {
\r
1091 throwPythonException(env, "Python variable not found");
\r
1095 if (!PyBool_Check(value)) {
\r
1096 throwPythonException(env, "Python variable not a boolean");
\r
1100 return value == Py_True;
\r
1103 JNIEXPORT jbooleanArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonBooleanArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1104 PyObject *module = getModule(contextID);
\r
1106 PyObject *pythonName = getPythonString(env, variableName);
\r
1108 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1109 if (value == NULL) {
\r
1110 throwPythonException(env, "Python variable not found");
\r
1114 if (!PySequence_Check(value)) {
\r
1115 throwPythonException(env, "Python variable not a sequence");
\r
1120 jbooleanArray result = pythonSequenceAsBooleanArray(env, value);
\r
1125 JNIEXPORT jlong JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonLongVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1126 PyObject *module = getModule(contextID);
\r
1128 PyObject *pythonName = getPythonString(env, variableName);
\r
1130 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1131 if (value == NULL) {
\r
1132 throwPythonException(env, "Python variable not found");
\r
1136 if (!PyLong_Check(value)) {
\r
1137 throwPythonException(env, "Python variable not an integer");
\r
1142 jlong result = PyLong_AsLongLong(value);
\r
1147 JNIEXPORT jintArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonIntegerArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1148 PyObject *module = getModule(contextID);
\r
1150 PyObject *pythonName = getPythonString(env, variableName);
\r
1152 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1153 if (value == NULL) {
\r
1154 throwPythonException(env, "Python variable not found");
\r
1158 if (!PySequence_Check(value)) {
\r
1159 throwPythonException(env, "Python variable not a sequence");
\r
1164 jintArray result = pythonSequenceAsIntegerArray(env, value);
\r
1169 JNIEXPORT jlongArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonLongArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1170 PyObject *module = getModule(contextID);
\r
1172 PyObject *pythonName = getPythonString(env, variableName);
\r
1174 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1175 if (value == NULL) {
\r
1176 throwPythonException(env, "Python variable not found");
\r
1180 if (!PySequence_Check(value)) {
\r
1181 throwPythonException(env, "Python variable not a sequence");
\r
1186 jlongArray result = pythonSequenceAsLongArray(env, value);
\r
1191 JNIEXPORT jdouble JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonDoubleVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1192 PyObject *module = getModule(contextID);
\r
1194 PyObject *pythonName = getPythonString(env, variableName);
\r
1196 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1197 if (value == NULL) {
\r
1198 throwPythonException(env, "Python variable not found");
\r
1202 if (!PyFloat_Check(value)) {
\r
1203 throwPythonException(env, "Python variable not a float");
\r
1208 jdouble result = PyFloat_AsDouble(value);
\r
1213 JNIEXPORT jdoubleArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonDoubleArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1214 PyObject *module = getModule(contextID);
\r
1216 PyObject *pythonName = getPythonString(env, variableName);
\r
1218 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1219 if (value == NULL) {
\r
1220 throwPythonException(env, "Python variable not found");
\r
1224 if (!PySequence_Check(value)) {
\r
1225 throwPythonException(env, "Python variable not a sequence");
\r
1230 jdoubleArray result = pythonSequenceAsDoubleArray(env, value);
\r
1235 JNIEXPORT jobject JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonNDArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1236 PyObject *module = getModule(contextID);
\r
1239 throwPythonException(env, "Importing numpy failed");
\r
1244 PyObject *pythonName = getPythonString(env, variableName);
\r
1246 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1247 if (value == NULL) {
\r
1248 throwPythonException(env, "Python variable not found");
\r
1252 if (!PyArray_Check(value)) {
\r
1253 throwPythonException(env, "Python variable not an ndarray");
\r
1257 if (PyArray_TYPE((PyArrayObject*)value) != NPY_DOUBLE) {
\r
1258 throwPythonException(env, "Only ndarrays of type double are supported");
\r
1263 jobject result = pythonArrayAsNDArray(env, (PyArrayObject *)value);
\r
1269 JNIEXPORT jobject JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariantVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1270 PyObject *module = getModule(contextID);
\r
1272 PyObject *pythonName = getPythonString(env, variableName);
\r
1274 PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
\r
1275 if (value == NULL) {
\r
1276 throwPythonException(env, "Python variable not found");
\r
1280 hasNumpy = _import_array() != -1;
\r
1283 jobject result = pythonObjectAsObject(env, value);
\r
1288 JNIEXPORT jint JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariableTypeImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {
\r
1289 PyObject *module = getModule(contextID);
\r
1290 PyObject *dict = PyModule_GetDict(module);
\r
1292 PyObject *pythonName = getPythonString(env, variableName);
\r
1294 if (!PyDict_Contains(dict, pythonName)) {
\r
1299 PyObject *value = PyDict_GetItem(dict, pythonName);
\r
1303 if (PyBool_Check(value))
\r
1305 else if (PyLong_Check(value))
\r
1307 else if (PyFloat_Check(value))
\r
1309 else if (PyUnicode_Check(value))
\r
1311 else if (PyByteArray_Check(value))
\r
1313 else if (PyDict_Check(value))
\r
1315 else if (hasNumpy && PyArray_Check(value))
\r
1317 else if (PySequence_Check(value))
\r
1326 JNIEXPORT jobjectArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariableNamesImpl(JNIEnv *env, jobject thisObj, jlong contextID) {
\r
1327 PyObject *module = getModule(contextID);
\r
1328 PyObject *dict = PyModule_GetDict(module);
\r
1330 PyObject *keys = PyDict_Keys(dict);
\r
1331 Py_ssize_t size = PyList_Size(keys);
\r
1333 jobjectArray result = (*env)->NewObjectArray(env, (jsize)size, (*env)->FindClass(env, STRING_CLASS), NULL);
\r
1336 for (i = 0; i < size; i++) {
\r
1337 jstring javaName = pythonStringAsJavaString(env, PyList_GetItem(keys, i));
\r
1338 (*env)->SetObjectArrayElement(env, result, (jint)i, javaName);
\r
1346 BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
\r
1347 //extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
\r
1349 switch (fdwReason)
\r
1351 case DLL_PROCESS_ATTACH:
\r
1352 // attach to process
\r
1353 // return FALSE to fail DLL load
\r
1356 case DLL_PROCESS_DETACH:
\r
1357 // detach from process
\r
1360 case DLL_THREAD_ATTACH:
\r
1361 // attach to thread
\r
1364 case DLL_THREAD_DETACH:
\r
1365 // detach from thread
\r
1368 return TRUE; // succesful
\r