我正在使用通过 JNA 加载的 C++ 库。我正在尝试对我的 java 程序进行多线程处理,但 C++ 库不是线程安全的,并且目前使库线程安全并不是一个现实的选择。我知道你一次只能加载一个库的副本,但我想如果我复制库文件并为每个线程都有一个副本,那么我就可以了。然而,我似乎发现情况并非如此:这里有两个测试。第一个加载库,执行一个方法,加载库的副本,然后执行相同的方法:它给了我一个错误。第二个只是加载一个库并执行该方法两次,并且不会引起任何问题。
是否无法加载库的两个副本,即使作为两个单独的文件(如果不能,是否有其他方法可以做到这一点?)错误看起来像 *** Error in `java': free (): 无效指针: 0x00007feb9001eba0 ***
错误也总是发生在测试结束时(看起来这些方法都工作正常,然后当测试结束时我收到错误)
public class NativeLibraryTest {
@Test
public void test() throws IOException {
final String libPath = "libjna.so";
final MyLibrary library = Native.loadLibrary(libpath, MyLibrary.class);
library.doThing();
final String libPath2 = "libjna_copy.so";
final MyLibrary library2 = Native.loadLibrary(libpath2, MyLibrary.class);
library2.doThing();
// get an error at the end of the test
}
@Test
public void testSingle() throws IOException {
final String libPath = "libjna.so";
final MyLibrary library = Native.loadLibrary(libpath, MyLibrary.class);
library.doThing();
library.doThing();
// no error
}
}
谢谢
最佳答案
对于 JNI,您不能多次加载同一个库,即使它已重命名。要执行的 native 方法仅通过其名称来标识,库名称将被忽略。
如果要加载两个库,则需要两个具有不同名称或包位置的 Java 类,为每个库定义 JNI 接口(interface)。 然后,您必须创建 JNI 编译器生成的头文件的两个实现。
无论如何,根据非线程安全库的实现,这仍然可能会导致问题。
恕我直言,唯一安全的方法是使用多个进程实现应用程序,然后使用进程间通信。使用非线程安全库的一个主进程和两个工作进程。
关于java - JNA 加载同一库的多个副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30332754/