2014-01-13 64 views
0

我試圖通過Java的Crypto ++包使用AES。因此,我在我的Java代碼中有兩個本地方法encryptdecrypt,然後它們被C包裝以訪問C++方法。 在命令行工作運行我的C++程序,但通過JNI從Java調用失敗與undefined symbol錯誤:JNI用「未定義符號」退出

Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/yves/temp/lib/libCI3CppEncryptionTools.so: /home/yves/temp/lib/libCI3CppEncryptionTools.so: undefined symbol: _ZTIN8CryptoPP6FilterE 

我通過它編譯:

g++ -c -Icryptopp562 -O3 -fwhole-program -fdata-sections -ffunction-sections -fPIC -fpermissive CI3CppEncryptionToolsImpl.cpp -Lcryptopp562 -lcryptopp 
gcc -I${JAVA_HOME}/include -O3 -fwhole-program -fdata-sections -ffunction-sections -Wall -shared -fPIC -o libCI3CppEncryptionTools.so CI3CppEncryptionTools.c CI3CppEncryptionToolsImpl.o -Wl,--gc-sections 

所以第一C++部分然後與C包裝器結合使用。 -fdata-sections,-ffunction-sections-Wl,--gc-sections是我試圖剝離死代碼,因爲我想也許JNI不喜歡未使用或未引用的代碼。

我檢查,如果該符號是通過使用未定義:

nm lib/libCI3CppEncryptionTools.so | grep _ZTIN8CryptoPP6FilterE 
U _ZTIN8CryptoPP6FilterE 

是的,它是。但爲什麼我的C++命令行程序工作?檢查這將產生相同的結果。

我也看了符號了:

c++filt _ZTIN8CryptoPP6FilterE 
typeinfo for CryptoPP::Filter 

CryptoPP::Filter頭是包括在內。我很好奇爲什麼它在檢查符號時顯示U

有沒有人有任何想法是什麼可能導致問題或在哪裏尋找旁邊解決問題?任何提示/見解都非常受歡迎!

+0

JNI入口點通常不會被您的庫引用,因此如果告訴GCC刪除未使用的符號,它是不是會刪除它們? –

+0

這可能是這種情況,但即使我刪除傳遞給GCC的這些參數,它仍然不起作用。 – yvesonline

回答

0

我總是忘了加密++庫在第二步鏈接(其實我這樣做是在第一步,這是完全廢話)。這兩個命令編譯庫就好了!

g++ -c -Icryptopp562 -O3 -fPIC -fpermissive CI3CppEncryptionToolsImpl.cpp 
gcc -I${JAVA_HOME}/include -O3 -shared -fPIC -o libCI3CppEncryptionTools.so CI3CppEncryptionTools.c CI3CppEncryptionToolsImpl.o -lcryptopp 
1

首先編譯您的CI3CppEncryptionTools.c,然後將其.o鏈接到.so中。要鏈接的.C

編輯:通過靜態的cryptocpp庫鏈接到你的共享庫:-Wl,--whole-archive libcryptocpp.a -Wl,--no-whole-archive

gcc -I${JAVA_HOME}/include -O3 -fwhole-program -fdata-sections -ffunction-sections -Wall -shared -fPIC -o libCI3CppEncryptionTools.so CI3CppEncryptionTools.c CI3CppEncryptionToolsImpl.o -Wl,--whole-archive libcryptocpp.a -Wl,--no-whole-archive -Wl,--gc-sections 
+0

嗯,不應該gcc首先編譯.c,然後傳遞結果.o和傳遞給鏈接器的.o。 – yvesonline

+0

@yvesonline當你運行這個命令時,你看到它編譯了.c嗎?你的nm命令告訴你這個函數是Undefined,所以它顯然不能編譯和包含代碼。 – Samhain

+0

提到的函數駐留在Crypto ++庫中。是的,.c被編譯。 – yvesonline