2011-08-07 114 views
5

我需要實現一個本地方法,比方說「public native void someFunc();」。我有兩個庫,libabc.so和libdef.so。 Java使用System.loadLibrary();加載libabc.so(不實現該方法),但JNI實現在libdef.so中。目前,我在libabc.so中執行以下操作。使用JNI加載另一個JNI庫?

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved){ 
JNIEnv *env; 
jclass cls; 
jmethodID get_load_id; 
jstring name; 

jvm->GetEnv((void**)&env, JNI_VERSION_1_4); 
cls = env->FindClass("java/lang/System"); 
get_load_id = env->GetStaticMethodID(cls, "load", "(Ljava/lang/String;)V"); 
name = env->NewStringUTF("/lib/libdef.so"); 
env->CallStaticVoidMethod(cls, get_load_id, name); 

return JNI_VERSION_1_4; 
} 

不過,我得到一個錯誤(於Android的logcat)如果我直接從Java加載libdef.so,我不」 「JNI_OnLoad在/lib/libdef.so返回的錯誤版本(-1)」噸得到這個錯誤。另外,如果我創建另一個本地方法「loadDef()」並使用相同的代碼實現它,它也可以工作。我想這個問題是使用jvm-> GetEnv(),但我不確定。另外,我甚至不知道這是否允許我實現我想要的(使用一個JNI庫加載另一個來實現)。我這樣做的原因很複雜,但沒有其他選擇。

+0

噢,一些更多的信息。在logcat上,在得到錯誤之前,我看到「試圖加載lib /lib/libdef.so 0x0」我想這意味着它試圖將庫加載到0x0。這是爲什麼? – Yifan

+0

我不確定期望'loadLibrary()'是可重入的是合理的。事實證明,這是從一個正常的本地方法工作似乎懷疑這種懷疑。你爲什麼不以這個複雜的理由來嘗試我們 - 也許我們可以幫助想出一個替代方案。 –

+0

我可以嘗試'RegisterNatives',但這意味着我必須手動加載庫並查找函數的位置。如果loadLibrary()不可重入,那就是問題所在,我可能必須這樣做。 – Yifan

回答

0

雖然我仍然沒有解決在JNI_OnLoad中加載另一個JNI庫的問題,但我找到了第一個被調用的本地函數,並將其替換,並在該函數中運行loadLibrary代碼。然後我再次從JNI調用本地方法,並運行該方法的新版本。