当我使用JNA在我的程序中调用不同的.so时,我遇到了一些问题。 我的本机共享库似乎无法声明具有相同名称的方法。
示例: 我有一个native1.c:
#include <stdio.h>
int anotherMethod() {
return 100;
}
int method() {
return 1 + anotherMethod();
}
还有native2.c:
#include <stdio.h>
int anotherMethod() {
return 200;
}
int method() {
return 2 + anotherMethod();
}
每个都在共享库(libnative1.so和libnative2.so)中编译。
$ gcc -m64 -shared -fPIC -o linux-x86-64/libnative1.so native1.c
$ gcc -m64 -shared -fPIC -o linux-x86-64/libnative2.so native2.c
(我在64位Linux上)
所以调用method()应该返回:
我将在一个小的Java Main中尝试它:
public static void main(String[] args) {
Native1 native1 = (Native1) Native.loadLibrary("native1", Native1.class);
Native2 native2 = (Native2) Native.loadLibrary("native2", Native2.class);
System.out.println(native1.method());
System.out.println(native2.method());
}
库接口是极简主义者:
public interface Native1 extends Library {
int method();
}
和
public interface Native2 extends Library {
int method();
}
我获得:
101 //好的
102 //应该是202!
这意味着调用了好的方法(),但是当我的本机代码调用anotherMethod()时,只调用native1中的一个。
我认为Native.loadLibrary()会加载我的共享库并将其展平,因此只存在第一个“anotherMethod”符号。
在我的真实案例中,C代码不在我的责任范围内,它是由另一个编辑提供的,所以我编辑它的次数越少越好
有没有办法轻松分隔每个共享库,比如命名空间或者我错过的gcc选项?
答案 0 :(得分:0)
拨打Native.loadLibrary()
时,您可以提供Map
个选项,其中包括密钥Library.OPTION_OPEN_FLAGS
,其值为RTLD_LOCAL
。这应该可以解决你的问题。
Map options = new HashMap();
int RTLD_LOCAL = 0x4; // or whatever value it has on your platform
options.put(Library.OPTION_OPEN_FLAGS, RTLD_LOCAL);
Mylib lib = Native.loadLibrary("mylib", Mylib.class, options);
您可以在目标系统上使用RTLD_LOCAL
查找grep RTLD_LOCAL /usr/include/*.h
的值。