У меня есть API, который я создаю, который вызывает собственные операции через C/C++. Я создал проект JNI и построил jnilib
используя следующие аргументы:
g++ -dynamiclib -rpath @loader_path -F /Users/nstuart/Downloads/myo-sdk -framework myo -framework JavaVM -o libmyo.jnilib *.o
Я пытаюсь, чтобы мой API был автономным, поэтому все библиотеки находятся в моих /src/main/resources, и я просто java.library.path
их в каталог temp перед установкой java.library.path
и загрузкой моей библиотеки JNI, Я получил это для работы в Windows, поскольку мне просто нужна моя JNI DLL и другая DLL, которую я тоже могу скопировать.
Когда я пытаюсь это сделать на Mac, у меня возникают проблемы:
Exception in thread "main" java.lang.UnsatisfiedLinkError: /private/var/folders/sf/3_7c7p452dq9jt_39yx76cn55rd8xh/T/libmyo.jnilib: dlopen(/private/var/folders/sf/3_7c7p452dq9jt_39yx76cn55rd8xh/T/libmyo.jnilib, 1): Library not loaded: @rpath/myo.framework/Versions/A/myo
Referenced from: /private/var/folders/sf/3_7c7p452dq9jt_39yx76cn55rd8xh/T/libmyo.jnilib
Reason: image not found
Я предполагаю, что это потому, что у меня @rpath
установлен мой @rpath
, и мне интересно, как правильно его настроить. С точки зрения java, где @rpath
? Если это относительный или в местоположении loader_path
, где это? Я предпочел бы иметь возможность установить это во время выполнения, чтобы я мог копировать файлы библиотеки, а затем указать, где они предназначены для программы.
В Java, как я могу определить: @rpath
? loader_path
? Где загружаются зависимые рамки?
Путь @rpath
работает каждый исполняемый файл, или библиотека заменяет @rpath
в имени установки инфраструктуры списком каталогов для поиска фреймворка при привязке к нему. Ошибка, которую вы видите, это libmyo.jnilib
, неспособный найти myo.framework
так как ее путь к @loader_path
значение @loader_path
, то есть он будет искать myo.framework
в /private/var/folders/sf/3_7c7p452dq9jt_39yx76cn55rd8xh/T/
.
Из того, что я могу сказать, у вас есть myo.framework
в /Users/nstuart/Downloads/myo-sdk
. Вы можете исправить эту проблему, отредактировав путь выполнения или перемещая myo.framework
в выходной каталог.
Ссылка: Myo SDK Справочный подраздел "Терминал"
Я получил эту работу для пресетов JavaCPP. В сторонних библиотеках, с которыми мы связываемся, нам нужно использовать install_name_tool
чтобы изменить все процессы сборки, поставленные там, в @rpath
(который является lib
в случае OpenCV), как показано этими строками в скрипте cppbuild.sh
для OpenCV:
VER=${OPENCV_VERSION:0:3}
BADPATH=lib
LIBS="../lib/libtbb.dylib ../lib/libopencv_*.$VER.dylib"
for f in $LIBS; do install_name_tool $f -id @rpath/'basename $f' \
-add_rpath /usr/local/lib/ -add_rpath /opt/local/lib/ -add_rpath @loader_path/. \
-change libtbb.dylib @rpath/libtbb.dylib \
-change $BADPATH/libopencv_core.$VER.dylib @rpath/libopencv_core.$VER.dylib \
-change $BADPATH/libopencv_calib3d.$VER.dylib @rpath/libopencv_calib3d.$VER.dylib \
-change $BADPATH/libopencv_features2d.$VER.dylib @rpath/libopencv_features2d.$VER.dylib \
-change $BADPATH/libopencv_flann.$VER.dylib @rpath/libopencv_flann.$VER.dylib \
-change $BADPATH/libopencv_gpu.$VER.dylib @rpath/libopencv_gpu.$VER.dylib \
-change $BADPATH/libopencv_highgui.$VER.dylib @rpath/libopencv_highgui.$VER.dylib \
-change $BADPATH/libopencv_imgproc.$VER.dylib @rpath/libopencv_imgproc.$VER.dylib \
-change $BADPATH/libopencv_legacy.$VER.dylib @rpath/libopencv_legacy.$VER.dylib \
-change $BADPATH/libopencv_ml.$VER.dylib @rpath/libopencv_ml.$VER.dylib \
-change $BADPATH/libopencv_nonfree.$VER.dylib @rpath/libopencv_nonfree.$VER.dylib \
-change $BADPATH/libopencv_objdetect.$VER.dylib @rpath/libopencv_objdetect.$VER.dylib \
-change $BADPATH/libopencv_photo.$VER.dylib @rpath/libopencv_photo.$VER.dylib \
-change $BADPATH/libopencv_video.$VER.dylib @rpath/libopencv_video.$VER.dylib; done
;;
Чтобы найти то, что у нас есть как BADPATH
для BADPATH
, мы можем использовать команду otool -L
. После исправления файла библиотеки рамок вам потребуется перестроить файл libmyo.jnilib
.