JNI以“未定义的符号”退出

时间:2014-01-13 14:13:57

标签: java c++ c gcc java-native-interface

我正在尝试通过Java的Crypto ++包使用AES。因此,我的Java代码中有两个本机方法encryptdecrypt,然后由C包装以访问C ++方法。 从命令行运行我的C ++程序,但通过JNI从Java调用它失败,出现undefined symbol错误:

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

有没有人知道什么可能导致问题或在哪里寻找解决问题?任何提示/见解都非常受欢迎!

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我总是忘记在第二步中链接Crypto ++库(实际上我是在第一步中完成的,这完全是胡说八道)。这两个命令编译库a-ok!

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