I’ve got two libraries, one with Ada objects and one with C++ objects (I don’t have a lot of control about which goes where)
The Ada stuff references the C stuff and vice versa…
This symbol is in libIPCAda.so: ipc_manager_shutdown_c
This symbol is in libIPCC.so: stream_buffer_header_size
When I do these JNA Calls:
CLibrary INSTANCE8 = (CLibrary)
Native.loadLibrary("IPCAda", // <<< our library goes here
CLibrary.class);
CLibrary INSTANCE9 = (CLibrary)
Native.loadLibrary("IPCC", // <<< our library goes here
CLibrary.class);
I get this:
ld.so.1: java: fatal: relocation error: file <<my directory>>/lib/libIPCAda.so: symbol stream_buffer_header_size: referenced symbol not found
When I do these JNA calls:
CLibrary INSTANCE9 = (CLibrary)
Native.loadLibrary("IPCC", // <<< our library goes here
CLibrary.class);
CLibrary INSTANCE8 = (CLibrary)
Native.loadLibrary("IPCAda", // <<< our library goes here
CLibrary.class);
I get this:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'IPCC': ld.so.1: java: fatal: relocation error: file <<my directory>>/lib/libIPCC.so: symbol ipc_manager_shutdown_c: referenced symbol not found
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:163)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:236)
at com.sun.jna.Library$Handler.<init>(Library.java:140)
at com.sun.jna.Native.loadLibrary(Native.java:379)
at com.sun.jna.Native.loadLibrary(Native.java:364)
at Test2$CLibrary.<clinit>(Test2.java:55)
at Test2.main(Test2.java:74)
Obviously its not liking the cross dependent symbols… Is there any way to make this work in JNA?
*EDIT Example Compile *
gcc -c -fPIC -g -O0 -fstack-check -pipe -gnatE -gnatU -gnatwl -gnatf -gnatE -gnat05 -lIPCC -I- -gnatA <<my directory>>src/ndds_c.adb
The cross-link is going to happen in native-code-land, not inside Java. As far as JNA knows, it’s loading two completely independent native libraries.
You need to supply the libraries themselves with each others’ locations. There are a couple ways to do this; either set the rpath when compiling the shared library, or set the LD_LIBRARY_PATH environment variable at run time.
Rpath is arguably the better method, since it’s specific to the binary that needs it, and doesn’t pollute the runtime environment. You can set it in gcc with the following compiler flags:
-Lpath-to-your-library -Wl,-rpath,path-to-your-library