Библиотеки загрузки JNA - PullRequest
7 голосов
/ 25 мая 2011

У меня есть две библиотеки, одна с объектами Ada и одна с объектами C ++ (у меня нет большого контроля над тем, куда и куда)

Ада ссылается на С и наоборот ...

Этот символ находится в libIPCAda.so: ipc_manager_shutdown_c

Этот символ находится в libIPCC.so: stream_buffer_header_size

Когда я делаю эти JNA Calls:

   CLibrary INSTANCE8 = (CLibrary)
   Native.loadLibrary("IPCAda", //  <<< our library goes here
                      CLibrary.class);

   CLibrary INSTANCE9 = (CLibrary)
   Native.loadLibrary("IPCC", //  <<< our library goes here
                      CLibrary.class);

Я получаю это:

ld.so.1: java: fatal: relocation error: file <<my directory>>/lib/libIPCAda.so: symbol stream_buffer_header_size: referenced symbol not found

Когда я делаю эти звонки JNA:

   CLibrary INSTANCE9 = (CLibrary)
   Native.loadLibrary("IPCC", //  <<< our library goes here
                      CLibrary.class);

   CLibrary INSTANCE8 = (CLibrary)
   Native.loadLibrary("IPCAda", //  <<< our library goes here
                      CLibrary.class);

Я получаю это:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'IPCC': ld.so.1: java: fatal: relocation error: file <<my directory>>/lib/libIPCC.so: symbol ipc_manager_shutdown_c: referenced symbol not found
    at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:163)
    at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:236)
    at com.sun.jna.Library$Handler.<init>(Library.java:140)
    at com.sun.jna.Native.loadLibrary(Native.java:379)
    at com.sun.jna.Native.loadLibrary(Native.java:364)
    at Test2$CLibrary.<clinit>(Test2.java:55)
    at Test2.main(Test2.java:74)

Очевидно, что не нравятся взаимозависимые символы ... Есть ли способ заставить это работать в JNA?

* РЕДАКТИРОВАТЬ Пример Компиляции *

gcc -c -fPIC -g -O0 -fstack-check -pipe -gnatE -gnatU -gnatwl -gnatf -gnatE -gnat05 -lIPCC -I- -gnatA <<my directory>>src/ndds_c.adb

Ответы [ 2 ]

6 голосов
/ 25 мая 2011

Перекрестная ссылка будет происходить в native-code-land, а не внутри Java. Насколько известно JNA, он загружает две совершенно независимые нативные библиотеки.

Вам необходимо предоставить самим библиотекам места расположения друг друга. Есть несколько способов сделать это; либо установите rpath при компиляции разделяемой библиотеки, либо установите переменную среды LD_LIBRARY_PATH во время выполнения.

Rpath, возможно, является лучшим методом, поскольку он специфичен для двоичного файла, который нуждается в нем, и не загрязняет среду выполнения. Вы можете установить его в gcc с помощью следующих флагов компилятора:

-Lpath-to-your-library -Wl,-rpath,path-to-your-library

1 голос
/ 05 июня 2011

Вы помещаете ВСЕ свои родные ключевые слова в одну 'CLibrary'?Поэтому, когда он выполняет первый Native.loadLibrary, он пытается отобразить все символы из первой загрузки во все ваши определенные Native методы.

Попробуйте разбить его на CLibrary1 и CLibrary2, где они точно соответствуют символу, который будет загружен библиотеками Ada и C.Я верю, что Java попытается отобразить все ваши нативные методы и потерпит неудачу на той половине, которая отсутствует в первом Native.loadLibrary.Java JNI не может загрузить искаженные символы C ++.Если вы, возможно, заставили реализацию экспортировать как символы C вместо этого, все будет в порядке.Не обменивайтесь C и C ++, когда говорите о нативных реализациях.

...