2015-05-19 5 views
1

Я использую библиотеку C++, которую загружаю через JNA. Я пытаюсь многопоточно переносить мою java-программу, но библиотека C++ не является потокобезопасной и делает потокобезопасность библиотеки не является реалистичным вариантом в настоящее время. Я знаю, что вы можете загружать только одну копию библиотеки за раз, но я подумал, что если бы я скопировал файл библиотеки и имел копию для каждого потока, тогда все было бы в порядке. Однако мне кажется, что это не так: вот два теста. Первый загружает библиотеку, выполняет метод, загружает копию библиотеки и выполняет тот же метод: он дает мне ошибку. Вторая просто загружает библиотеку и дважды выполняет этот метод, и это не вызывает проблем.JNA загружает несколько копий одной и той же библиотеки

Невозможно загрузить две копии библиотеки даже в виде двух отдельных файлов (а если нет, есть ли другой способ сделать это?) Ошибки выглядят как *** 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

Для JNI вы не можете загрузить ту же самую библиотеку более чем один раз, даже если это переименованы. Собственный метод, который должен быть выполнен, идентифицируется только по его имени, имя библиотеки игнорируется.

Если вы хотите загрузить две библиотеки, вам понадобятся два Java-класса с различным именем или расположением пакетов, определяющими интерфейс JNI для каждой библиотеки. Затем вам нужно создать две реализации файла заголовка, сгенерированного компилятором JNI.

В любом случае, в зависимости от реализации библиотеки, не связанной с потоками, это все равно может вызвать проблемы.

IMHO единственным безопасным способом является внедрение приложения с использованием нескольких процессов, а затем использование межпроцессного взаимодействия. Один основной процесс и два рабочих процесса с использованием не-потоковой библиотеки.

Смежные вопросы