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

时间:2015-05-19 17:52:26

标签: java jna

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

}

由于

1 个答案:

答案 0 :(得分:1)

对于JNI,即使重命名,也无法多次加载同一个库。要执行的本机方法仅由其名称标识,库名称将被忽略。

如果要加载两个库,则需要两个具有不同名称或包位置的Java类,以定义每个库的JNI接口。 然后,您必须创建由JNI编译器生成的头文件的两个实现。

无论如何,根据非线程安全库的实现,这可能仍会造成麻烦。

IMHO唯一安全的方法是使用多个进程实现您的应用程序,然后使用进程间通信。一个主要进程和两个使用非线程安全库的工作进程。