JNA加载库

发布于 2024-11-09 10:23:28 字数 2028 浏览 3 评论 0原文

我有两个库,一个包含 Ada 对象,一个包含 C++ 对象(我对哪个库去哪里没有太多控制)

Ada 内容引用 C 内容,反之亦然...

这个符号位于 libIPCAda 中。所以:ipc_manager_shutdown_c

这个符号在libIPCC.so中:stream_buffer_header_size

当我执行这些JNA调用时:

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

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

我得到这个:

ld.so.1: java: fatal: relocation error: file <<my directory>>/lib/libIPCAda.so: symbol stream_buffer_header_size: referenced symbol not found

当我执行这些JNA时调用:

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

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

我明白了:

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)

显然它不喜欢交叉依赖符号...有什么方法可以在 JNA 中实现此功能吗?

*编辑示例编译*

gcc -c -fPIC -g -O0 -fstack-check -pipe -gnatE -gnatU -gnatwl -gnatf -gnatE -gnat05 -lIPCC -I- -gnatA <<my directory>>src/ndds_c.adb

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

許願樹丅啲祈禱 2024-11-16 10:23:28

交叉链接将发生在本机代码领域,而不是 Java 内部。据 JNA 所知,它正在加载两个完全独立的本机库。

您需要向图书馆本身提供彼此的位置。有几种方法可以做到这一点;可以在编译共享库时设置 rpath,也可以在运行时设置 LD_LIBRARY_PATH 环境变量。

Rpath 可以说是更好的方法,因为它特定于需要它的二进制文件,并且不会污染运行时环境。您可以使用以下编译器标志在 gcc 中设置它:

<代码>
-L 库路径 -Wl,-rpath,库路径

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

·深蓝 2024-11-16 10:23:28

您是否将所有原生关键字放入一个“CLibrary”中?因此,当它执行第一个 Native.loadLibrary 时,它会尝试将第一次加载中的所有符号映射到所有 Native 定义的方法。

尝试将其分解为 CLibrary1 和 CLibrary2,它们与将由 Ada 和 C 库加载的符号完全对应。我相信 Java 会尝试映射所有本机方法,并且会在第一个 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);

你还提到了C++。 Java JNI 无法加载 C++ 损坏的符号。如果您可能强制将实现导出为 C 符号,那么您就可以了。在谈论本机实现时,不要交换 C 和 C++。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文