JNA 加载同一个库的多个副本
JNA load multiple copies of the same library
我正在使用通过 JNA 加载的 C++ 库。我正在尝试对我的 java 程序进行多线程处理,但是 C++ 库不是线程安全的,并且使库线程安全目前不是一个现实的选择。我知道你一次只能加载一个库的一个副本,但我认为如果我复制库文件并为每个线程都有一个副本,那么我会没事的。但是,我似乎发现情况并非如此:这里有两个测试。第一个加载一个库,执行一个方法,加载一个库的副本,然后执行相同的方法:它给我一个错误。第二个简单地加载一个库并执行该方法两次,它不会导致任何问题。
即使作为两个单独的文件加载库的两个副本是不可能的吗(如果不能,还有其他方法吗?)错误看起来像*** Error in `java': free(): invalid pointer: 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,您不能多次加载同一个库,即使它已重命名。要执行的本机方法仅由其名称标识,忽略库名称。
如果你想加载两个库,你需要两个 Java 类 具有不同的名称或包位置定义每个库的 JNI 接口。
然后,您必须创建 JNI 编译器生成的头文件的两个实现。
无论如何,根据非线程安全库的实现,这可能仍然会造成问题。
恕我直言,唯一安全的方法是使用多个进程实现您的应用程序,然后使用进程间通信。一个主进程和两个工作进程使用非线程安全库。
我正在使用通过 JNA 加载的 C++ 库。我正在尝试对我的 java 程序进行多线程处理,但是 C++ 库不是线程安全的,并且使库线程安全目前不是一个现实的选择。我知道你一次只能加载一个库的一个副本,但我认为如果我复制库文件并为每个线程都有一个副本,那么我会没事的。但是,我似乎发现情况并非如此:这里有两个测试。第一个加载一个库,执行一个方法,加载一个库的副本,然后执行相同的方法:它给我一个错误。第二个简单地加载一个库并执行该方法两次,它不会导致任何问题。
即使作为两个单独的文件加载库的两个副本是不可能的吗(如果不能,还有其他方法吗?)错误看起来像*** Error in `java': free(): invalid pointer: 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,您不能多次加载同一个库,即使它已重命名。要执行的本机方法仅由其名称标识,忽略库名称。
如果你想加载两个库,你需要两个 Java 类 具有不同的名称或包位置定义每个库的 JNI 接口。 然后,您必须创建 JNI 编译器生成的头文件的两个实现。
无论如何,根据非线程安全库的实现,这可能仍然会造成问题。
恕我直言,唯一安全的方法是使用多个进程实现您的应用程序,然后使用进程间通信。一个主进程和两个工作进程使用非线程安全库。