java - JNA 加载同一库的多个副本

标签 java jna

我正在使用通过 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/

相关文章:

java - 通过进程Id获取进程对象

java - 选项卡未显示(ViewPager)

java - 如何通知 Java 桌面客户端有关服务器的更改?

java - GUI 部分未显示

java - JNA 如何使用 HWND_BROADCAST

c# - 将 native C# 调用转换为 Java(使用 JNA)

java - android.database.sqlite.SQLiteDiskIOException

java - Android 动态壁纸问题

Java (JNA) dll 的引用传递

c++ - 从 ShellExecute 获取 PID