java.lang.UnsatisfiedLinkError после связывания C-оболочек для JNI

Я надеюсь, что кто-то может помочь мне с моей проблемой. Я компилирую в Linux некоторую оболочку C для JNI, которая изначально была создана для Windows (у меня был вопрос, который уже был решен [здесь] [1]). Моя текущая проблема заключается в следующем.

Код в основном состоит из aaa.c, aaa.h, bbb.c и bbb.h.

aaa.h — это заголовок, сгенерированный инструментом javah.

aaa.c является реализацией aaa.h bbb.h и bbb.c имеют некоторые

функции, вызываемые aaa.c, одна из них:

int jstring2char(JNIEnv*, jstring, char**);

Теперь я создал проект в Code::Blocks. Когда проект построен, выполняются следующие команды:

gcc -Wall  -g -D_GNU_SOURCE -DUNIX    -I../somepath/Inc -I/usr/local/jdk1.7.0_40/include/linux -I/usr/local/jdk1.7.0_40/include  -c /somepath/Scr/aaa.c -o obj/Debug/aaa.o
gcc -Wall  -g -D_GNU_SOURCE -DUNIX    -I../somepath/Inc -I/usr/local/jdk1.7.0_40/include/linux -I/usr/local/jdk1.7.0_40/include  -c /somepath/Scr/bbb.c -o obj/Debug/bbb.o
g++ -shared  obj/Debug/aaa.o obj/Debug/bbb.o   -o bin/Debug/libWrapper.so  

Процесс завершен с 0 ошибками, 0 предупреждениями.

Затем я установил библиотеку в /opt/somepath:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/somepath

Теперь, когда я пытаюсь загрузить сгенерированную библиотеку

System.loadLibrary("libWrapper.so");

Ошибка:

Исключение в потоке main java.lang.UnsatisfiedLinkError: нет libWrapper.so в java.library.path

генерируется. Мое первое предположение состоит в том, что есть какая-то неудовлетворенная зависимость, поэтому я rn ldd:

root@Ubuntu10:/opt/somepath# ldd libWrapper.so
    linux-gate.so.1 =>  (0x00110000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00161000)
    libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x00111000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00662000)
    libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00bae000)
    /lib/ld-linux.so.2 (0x00915000)

Итак, моя первая проблема заключается в том, что я не знаю, является ли linux-gate.so.1 причиной проблемы.

С другой стороны, я проверил, загрузив библиотеку с помощью jna API, просто чтобы проверить, было ли более конкретное сообщение об ошибке:

Native.loadLibrary("libWrapper.so", SClass.class);

По сути, я получил другое сообщение:

Исключение в потоке main java.lang.UnsatisfiedLinkError: невозможно загрузить библиотеку 'libWrapper.so': libWrapper.so: неопределенный символ: jstring2char

jstring2char — это функция, объявленная в bbb.h, реализованная в bbb.c, которая вызывается aaa.c. Теперь кажется, что aaa.c не разрешает функции bbb.c, несмотря на то, что они оба были связаны во время сборки.

Теперь мои вопросы: что может быть причиной ошибки UnsatisfiedLinkError, linux-gate.so.1 или функции jstring2char? Какие подсказки может дать мне сообщество?

Спасибо большое. [1]:


person Ferite    schedule 25.09.2013    source источник
comment
Что такое нативная функция (в Java и в заголовке)?   -  person Kerrek SB    schedule 26.09.2013


Ответы (1)


Вам нужно сказать:

System.loadLibrary("Wrapper");

Имя файла вычисляется автоматически в зависимости от вашей системы (например, в Windows это будет Wrapper.dll).

person Kerrek SB    schedule 25.09.2013
comment
Спасибо за подсказку, Керрек. Теперь я получил ту же ошибку с System.loadLibrary и Native.loadLibrary (неопределенный символ: jstring2char). Это решает часть моей проблемы. Другая часть заключается в том, почему aaa.c не может вызывать функции bbb.c, если они оба связаны друг с другом :( - person Ferite; 26.09.2013
comment
@Ferite: вы скомпилировали с -fPIC? - person Kerrek SB; 26.09.2013
comment
Я добавил в проект опцию -fPIC. IDE добавила параметр в команду компиляции файлов, а не в сборку общей библиотеки. Однако результат тот же, когда библиотека загружена. - person Ferite; 26.09.2013
comment
Наконец, помимо очевидной ошибки, о которой здесь не стоит упоминать, единственной проблемой было неправильное имя при загрузке библиотеки, поэтому ответ @Kerrek SB был решением. - person Ferite; 02.10.2013