簡體   English   中英

Java使用JNI導入使用第三者功能(Python.h)的C中的共享庫

[英]Java use JNI to import shared library in C that uses 3rd party functionality (Python.h)

從“ 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;
}

和用javah -jni生成的頭文件...

創建lib.so文件可以正常工作。 我的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());
        }
    }
}

運行程序時的結果:線程“ main”中的異常java.lang.UnsatisfiedLinkError:/pathtomyso/lib.so:/pathtomyso/lib.so:未定義符號:Py_Initialize

您知道為什么Python.h的Py_Initialize功能未知嗎?

編輯:1我用谷歌搜索,似乎得到了錯誤的答案。 現在我使用:

cc lib.c -o lib.so  -I/usr/lib/jvm/java-7-openjdk-i386/include/ -I /usr/include/python2.7 -lpython2.7 -shared -lc

但是我仍然有一些錯誤。 我的python模塊將python包裝器用於blueZ Bluetooth-Stack。 但由於某種原因,它無法導入集成在此模塊中的共享庫:

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

我遇到了類似的問題,並且已經解決了。 我的問題和解決方案:Java通過JNA調用liba.so,liba.so調用libb.so,libb.so調用python腳本。 在liba.so中,應使用RTLD_NOW | dlopen中的RTLD_GLOBAL。 就這樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM