Reputation: 4837
I'm trying to use AES via the Crypto++ package from Java. Therefore I have two native methods encrypt
and decrypt
in my Java code which are then wrapped by C in order to access the C++ methods.
Running my C++ program from the command line works, but calling it from Java via JNI fails with an undefined symbol
error:
Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/yves/temp/lib/libCI3CppEncryptionTools.so: /home/yves/temp/lib/libCI3CppEncryptionTools.so: undefined symbol: _ZTIN8CryptoPP6FilterE
I'm compiling it via:
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
So first the C++ part and then combined with the C wrapper. -fdata-sections
, -ffunction-sections
and -Wl,--gc-sections
were my attempt to strip dead code because I thought maybe JNI does not like unused or unreferenced code.
I checked if the symbol is undefined by using:
nm lib/libCI3CppEncryptionTools.so | grep _ZTIN8CryptoPP6FilterE
U _ZTIN8CryptoPP6FilterE
And yes, it is. But why is my C++ command line program working? Checking this yields the same result.
I also looked the symbol up:
c++filt _ZTIN8CryptoPP6FilterE
typeinfo for CryptoPP::Filter
The header for CryptoPP::Filter
is included. I'm curious why it says U
when checking for the symbol.
Does anyone have any idea what could cause the problem or where to look next to solve the problem? Any hints/insights are highly welcome!
Upvotes: 0
Views: 1404
Reputation: 4837
I always forgot to link the Crypto++ library in the second step (actually I did it in the first step, which was complete nonsense). Those two commands compile the library 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
Upvotes: 1
Reputation: 1765
Compile your CI3CppEncryptionTools.c first, then link its .o into the .so. You are linking the .c
Edit: Statically link your cryptocpp library into your shared library via : -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
Upvotes: 1