[英]Java use JNI to import shared library in C that uses 3rd party functionality (Python.h)
I have a problem with my JNI integration of "lib.so" that is compiled from "lib.c" that looks like: 从“ lib.c”编译的“ lib.so”的JNI集成出现问题,如下所示:
#include <jni.h>
#include "messageService.h"
#include <Python.h>
PyObject *pName, *pModule, *pDict, *pFunc;
PyObject *pArgs, *pValue;
JNIEXPORT jboolean JNICALL Java_Test_test
(JNIEnv * pEnv, jclass clazz)
{
Py_Initialize();
pName = PyString_FromString("mylib");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule,"test");
if (pFunc && PyCallable_Check(pFunc)) {
PyObject_CallObject(pFunc, NULL);
Py_DECREF(pFunc);
if (PyErr_Occurred()){
PyErr_Print();
jclass exc = (*pEnv)->FindClass( pEnv, "java/lang/Exception" );
if ( exc != NULL )
(*pEnv)->ThrowNew( pEnv, exc, "in C code; Error while executing \"test\"" );
return (jboolean) 0;
}
return (jboolean) 1;
}
else {
if (PyErr_Occurred())
PyErr_Print();
jclass exc = (*pEnv)->FindClass( pEnv, "java/lang/Exception" );
if ( exc != NULL )
(*pEnv)->ThrowNew( pEnv, exc, "in C code; Cannot find function \"test\"" );
return (jboolean) 0;
}
Py_XDECREF(pFunc);
return (jboolean) 0;
}
else {
PyErr_Print();
jclass exc = (*pEnv)->FindClass( pEnv, "java/lang/Exception" );
if ( exc != NULL )
(*pEnv)->ThrowNew( pEnv, exc, "in C code; Failed to load \"mylib\"" );
}
return (jboolean) 0;
}
and the header file generated with javah -jni ... 和用javah -jni生成的头文件...
Creating the lib.so file works fine. 创建lib.so文件可以正常工作。 My java programm:
我的java程序:
public class Test {
static{
System.load("/pathtomyso/lib.so")
}
public static native boolean test();
public static void main(String[] args){
boolean result = false;
try{
result = Test.test();
System.out.println(result);
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
The result when I run my programm: Exception in thread "main" java.lang.UnsatisfiedLinkError: /pathtomyso/lib.so: /pathtomyso/lib.so: undefined symbol: Py_Initialize 运行程序时的结果:线程“ main”中的异常java.lang.UnsatisfiedLinkError:/pathtomyso/lib.so:/pathtomyso/lib.so:未定义符号:Py_Initialize
Do you know why the functionality Py_Initialize from Python.h is unknown? 您知道为什么Python.h的Py_Initialize功能未知吗?
EDIT:1 I googled and got a wrong answer it seems. 编辑:1我用谷歌搜索,似乎得到了错误的答案。 Now I use:
现在我使用:
cc lib.c -o lib.so -I/usr/lib/jvm/java-7-openjdk-i386/include/ -I /usr/include/python2.7 -lpython2.7 -shared -lc
But still I have some errors. 但是我仍然有一些错误。 My python module uses python wrappers for blueZ Bluetooth-Stack.
我的python模块将python包装器用于blueZ Bluetooth-Stack。 But somehow it cannot import the shared library integrated in this module:
但由于某种原因,它无法导入集成在此模块中的共享库:
File "/usr/local/lib/python2.7/dist-packages/mylib.egg/mylib/test.py", line 10, in <module>
import bluetooth
File "/usr/local/lib/python2.7/dist-packages/bluetooth/__init__.py", line 34, in <module>
from bluez import *
File "/usr/local/lib/python2.7/dist-packages/bluetooth/bluez.py", line 6, in <module>
import _bluetooth as _bt
/usr/local/lib/python2.7/dist-packages/bluetooth/_bluetooth.so: undefined symbol: PyExc_ValueError
I met the similar problem and had solved it. 我遇到了类似的问题,并且已经解决了。 My problem and solution: Java call liba.so via JNA, liba.so call libb.so, libb.so call python script.
我的问题和解决方案:Java通过JNA调用liba.so,liba.so调用libb.so,libb.so调用python脚本。 In the liba.so, you should use RTLD_NOW |
在liba.so中,应使用RTLD_NOW | RTLD_GLOBAL in the dlopen.
dlopen中的RTLD_GLOBAL。 That's all.
就这样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.