JNA 加载许多具有相同方法名称的库
JNA loading many libraries with same method name
我在程序中使用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() 应该 return :
- 101 in native1
- 202 in native2
我会小试一下Java 主要:
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 // OK
102 // Should be 202 !
这意味着调用了好的方法(),但是当我的本机代码调用另一个方法()时,只调用了native1中的方法。
我认为 Native.loadLibrary() 加载我的共享库并将其展平,因此只有第一个“anotherMethod”符号存在。
在我的真实案例中,C 代码不在我的责任范围内,它是由另一个编辑器提供的,所以我编辑的越少越好
有没有办法轻松地分离每个共享库,比如在命名空间中或者我错过的 gcc 选项?
调用 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);
您可以在目标系统上使用 grep RTLD_LOCAL /usr/include/*.h
查找 RTLD_LOCAL
的值。
我在程序中使用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() 应该 return :
- 101 in native1
- 202 in native2
我会小试一下Java 主要:
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 // OK
102 // Should be 202 !
这意味着调用了好的方法(),但是当我的本机代码调用另一个方法()时,只调用了native1中的方法。
我认为 Native.loadLibrary() 加载我的共享库并将其展平,因此只有第一个“anotherMethod”符号存在。
在我的真实案例中,C 代码不在我的责任范围内,它是由另一个编辑器提供的,所以我编辑的越少越好
有没有办法轻松地分离每个共享库,比如在命名空间中或者我错过的 gcc 选项?
调用 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);
您可以在目标系统上使用 grep RTLD_LOCAL /usr/include/*.h
查找 RTLD_LOCAL
的值。