I am trying to call python from a JNI library. This works as expected and thanks to all the information around on the interweb.
My problem begins when I try to "import numpy as np". When I include that in any python script, PyImport_Import(pName) in the code below returns null. Without the check for null, the program (expectedly) issues a segmentation violation.
I am using Java 7 (openjdk-amd64), Ubuntu 13.04, gcc 4.7.3
The code below is a snippet of the python interpreter initialisation and call. It is compiled into a shared object loaded by Java. If the same code is included in a normal program, the python script runs exactly as expected.
My guess is that numpy is unable to load libraries it requires when run via java and the shared JNI library. But after 48 hours of work, I'm clueless as to what I need to say to it to make it work.
int call_python(char *module, char *function, PyObject *list)
{
PyObject *pName, *pModule, *pDict, *pFunc, *pValue;
Py_Initialize();
printf("Initialized\n");
pName = PyString_FromString(module);
printf("pName created from: '%s'\n", module);
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\".\")");
PyRun_SimpleString("sys.path.append(\"/home/jonathan/swigtests/j2p\")");
PyRun_SimpleString("print \"Interpreter Running\"");
pModule = PyImport_Import(pName);
if (pModule == (PyObject *)NULL)
{
printf("Unable to load '%s'\n", module);
return 0;
}
printf("Checking pmodule...%x\n", (int)pModule);
if (!PyModule_Check(pModule))
printf("pModule is not a module!\n");
else
printf("pModule is a module!\n");
pDict = PyModule_GetDict(pModule);
pFunc = PyDict_GetItemString(pDict, function);
PyObject *arglist = Py_BuildValue("(i)", 1);
PyDict_SetItemString(pDict, "field", list);
if (PyCallable_Check(pFunc))
{
printf("Calling Python\n");
//if (PyObject_CallFunction(pFunc, "i", 2) == NULL)
if (PyObject_CallObject(pFunc, arglist) == NULL)
printf("CallFunction failed\n");
else
printf("CallFunction succeeded\n");
}
else
{
printf("Not callable\n");
PyErr_Print();
}
printf("Python done\n");
Py_DECREF(pModule);
Py_DECREF(pName);
Py_Finalize();
return 0;
}
Update. I added PyErr_Print after printf("Unable to load")... This yields the traceback printout that is helpful:
Traceback (most recent call last):
File "./py_function.py", line 3, in <module>
import numpy as np
File "/usr/lib/python2.7/dist-packages/numpy/__init__.py", line 137, in <module>
import add_newdocs
File "/usr/lib/python2.7/dist-packages/numpy/add_newdocs.py", line 9, in <module>
from numpy.lib import add_newdoc
File "/usr/lib/python2.7/dist-packages/numpy/lib/__init__.py", line 4, in <module>
from type_check import *
File "/usr/lib/python2.7/dist-packages/numpy/lib/type_check.py", line 8, in <module>
import numpy.core.numeric as _nx
File "/usr/lib/python2.7/dist-packages/numpy/core/__init__.py", line 5, in <module>
import multiarray
ImportError: /usr/lib/python2.7/dist-packages/numpy/core/multiarray.so: undefined symbol: PyExc_SystemError
This starts to look like another problem reported with DateTime:
https://mail.python.org/pipermail//capi-sig/2013-August/000600.html
Exactly the same as this problem:
How to allow 3rd-party libraries to be imported by scripts called in embedded Python interpreter?