简体   繁体   中英

JNA loading libraries

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

Are you putting ALL your native keywords in a single 'CLibrary'? So when it does the first Native.loadLibrary it tries mapping all of the symbols from the first load to all of your Native defined methods.

Try breaking it up in to CLibrary1 and CLibrary2, where they correspond exactly to the symbol that will get loaded by the Ada and C libraries. I believe Java will try mapping all of your native methods and will fail on the half that is missing from the first Native.loadLibrary.

CLibrary INSTANCE9 = (CLibrary)
Native.loadLibrary("IPCC", //  <<< our library goes here
                  CLibrary.class);

AdaLibrary INSTANCE8 = (AdaLibrary)
Native.loadLibrary("IPCAda", //  <<< our library goes here
                  AdaLibrary.class);

You also mention C++. Java JNI cannot load C++ mangled symbols. If you perhaps forced the implementation to export as C symbols instead you'll be ok. Don't exchange C and C++ when talking about native implementations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM