Я следил за этим руководством. Начиная 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?
прежде всего, вы должны получить базовое представление о родных библиотеках на своей платформе. Существуют статические и динамические библиотеки.
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.