У меня есть 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
и загружаю мою библиотеку 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
? Если это относительно, или на loader_path
место, где это? Я предпочел бы иметь возможность установить это во время выполнения так, чтобы я мог копировать свои файлы библиотеки, а затем указывать, где они находятся для программы.
На Java, как мне определить: @rpath
? loader_path
? Откуда загружаются зависимые фреймворки?
Путь @rpath
работает каждый исполняемый файл или библиотека заменяет @rpath
в имени установки фреймворка со списком каталогов для поиска фреймворка при ссылке на него. Ошибка, которую вы видите libmyo.jnilib
будучи не в состоянии найти myo.framework
поскольку его путь запуска установлен в @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
для myo, мы можем использовать otool -L
команда. Как только файл библиотеки фреймворка будет исправлен, вам нужно будет восстановить libmyo.jnilib
файл.