Java JNI 'C' код с внешними библиотеками

1

Я следил за этим руководством. Начиная JNI с NetBeans IDE и C/C++ плагин на Linux для запуска кода "C" из моего приложения Java, и все сработало.

Моя проблема в том, что когда я пытаюсь использовать внешние библиотеки (например, amqp.h), я получаю сообщение об ошибке:

ошибка поиска символа: /home/amir/NetBeansProjects/c_pcap_parser/lib/c_pcap_parser.so: undefined symbol: amqp_new_connection Java Результат: 127

Как я включаю библиотеки в мой последний файл.so?

Теги:
jni

1 ответ

2
Лучший ответ

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

Static означает, что весь собственный код добавляется в файл библиотеки для повторного использования. Поэтому, если вы уже скомпилировали некоторый код C, вы будете знать о файлах *.o, которые содержат двоичный код, который понимается вашим процессором. Статическая библиотека - всего лишь их коллекция. Обычно они имеют расширение файла.a на платформах Linux. При связывании со статической библиотекой в ваш приложение будет добавлен весь собственный код вставки (скажем, вашему исполняемому файлу).

Напротив, динамическая библиотека не будет физически добавляться в ваш исполняемый файл, она будет указана, если требуется, из глобального системного каталога (это похоже на среду PATH). Они называются общими объектами в linux (extention.so). Существует также переменная окружения для этого на большинстве платформ, я думаю, что это называется LD_LIBRARY_PATH (см это переполнение стека для destinction). Все каталоги переменной среды будут найдены для общих объектов, которые могут быть связаны во время запуска вашего приложения.

Хорошо с учетом этого, вы можете попытаться решить проблему. Я полагаю, что amqp.h принадлежит клиенту C rabbitmq. Если вы хотите использовать этот код c в java, вам нужно сначала скомпилировать его на своей платформе. Это делается, следуя описанию на странице проекта github, на которую я ссылался выше.

Хорошо, после успешного процесса сборки вы получите некоторый файл библиотеки из компиляции, я думаю, что они создадут динамическую библиотеку, но я не уверен в этом. Результат этого результата определяет ваше действие для вашего java-кода. Если это динамическая библиотека, достаточно было бы добавить общий объект в путь библиотеки java. Это также показано в учебнике, на который вы ссылались. Я просто добавил запись для потенциального общего объекта библиотеки rabbitmq c:

static {
    System.load("full-path-to-NetBeansProjects-dir/JNIDemoCdl/dist/libJNIDemoCdl.so");
    System.load("full-path-to-dir-where-the-rabbitmq-so-lives-in/librabbitmq.so");   
}

Если бы это была статическая библиотека, вам действительно нужно было бы по-другому разбираться в этом. Вам нужно будет связать библиотеку librabbitmq.a во время компиляции C, чтобы правильно перевести вещи. В учебнике, упомянутом в вашем вопросе, я увидел, что Netbeans имеет раздел компоновщика для компилятора C, в котором вы можете добавить статический lib rabbitmq во время компиляции C.

Один отказ от ответственности: если вы просто хотите получить доступ к rabbitmq с помощью java-кода, конечно, также выходит из java-библиотеки, которая должна быть намного проще использовать с rabbitmq (вам не понадобятся все компиляции JNI и C).

Также одно примечание к данному учебнику в вашем вопросе: они скомпилируют C-код с флагом -m32, который создает 32-битный общий объект. Если вы последуете моим инструкциям выше, это может быть проблемой! Причина в том, что вам нужно скомпилировать клиент rabbitmq C с этим флагом, до 32 бит. Компилятор gcc по умолчанию на большинстве платформ будет создавать 64-битные библиотеки, которые не совместимы с 32-разрядной JVM и 32-разрядной общей библиотекой. Поэтому убедитесь, что все 32 бит или 64 бит, но в любом случае не смешиваются! Например, находясь на 64-битной машине с 64-разрядной JVM, вы должны удалить флаг -m32.

  • 0
    Большое спасибо за объяснение. Я попробую и обновлю соответственно.
  • 0
    Я попробовал ваше предложение и собрал код rabbitmq-c с помощью cmake, но он не сработал. Я получил 3 файла: librabbitmq.so, librabbitmq.so.1, librabbitmq.so.1.2.2. Я загрузил файл librabbitmq.so, но получаю то же сообщение об ошибке «неопределенный символ: amqp_new_connection» (это функция rabbitmq-c).
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню