JNI退出"undefined symbol"

JNI exits with "undefined symbol"

本文关键字:symbol undefined JNI 退出      更新时间:2023-10-16

我正试图通过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

有人知道是什么导致了问题,或者下一步该去哪里解决问题吗?非常欢迎任何提示/见解!

首先编译您的CI3CppEncryptionTools.c,然后将其.o链接到.so。您正在链接.c

编辑:通过:-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

我总是忘记在第二步链接Crypto++库(实际上我在第一步就链接了,这完全是无稽之谈)。这两个命令编译库是好的!

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