首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JNA加载库

JNA加载库
EN

Stack Overflow用户
提问于 2011-05-25 18:35:14
回答 2查看 4.3K关注 0票数 7

我有两个库,一个是Ada对象,另一个是C++对象(我对哪种情况没有太多的控制)

Ada指的是C,反之亦然.

这个符号在libIPCAda.so: libIPCAda.so中

这个符号在libIPCC.so: libIPCC.so中

当我做这些JNA电话时:

代码语言:javascript
复制
   CLibrary INSTANCE8 = (CLibrary)
   Native.loadLibrary("IPCAda", //  <<< our library goes here
                      CLibrary.class);

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

我明白了:

代码语言:javascript
复制
ld.so.1: java: fatal: relocation error: file <<my directory>>/lib/libIPCAda.so: symbol stream_buffer_header_size: referenced symbol not found

当我做这些JNA电话时:

代码语言:javascript
复制
   CLibrary INSTANCE9 = (CLibrary)
   Native.loadLibrary("IPCC", //  <<< our library goes here
                      CLibrary.class);

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

我明白了:

代码语言:javascript
复制
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)

显然它不喜欢交叉相依的符号..。在南航有什么办法让这件事奏效吗?

*编辑示例编译*

代码语言:javascript
复制
gcc -c -fPIC -g -O0 -fstack-check -pipe -gnatE -gnatU -gnatwl -gnatf -gnatE -gnat05 -lIPCC -I- -gnatA <<my directory>>src/ndds_c.adb
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-05-25 19:44:04

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

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

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

-Lpath-to-your-library -Wl,-rpath,path-to-your-library

票数 6
EN

Stack Overflow用户

发布于 2011-06-05 12:33:33

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

尝试将其拆分到CLibrary1和CLibrary2,它们完全对应于Ada和C库将要加载的符号。我相信Java将尝试映射您的所有本机方法,并在第一个Native.loadLibrary中缺少的一半上失败。

代码语言:javascript
复制
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无法加载C++损坏的符号。如果您可能强迫实现导出为C符号,那么您就可以了。在谈论本机实现时,不要交换C和C++。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6129165

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档