Android NDK С++ JNI (нет реализации для родных...)
Я пытаюсь использовать NDK с С++ и, похоже, не верю правильно. мой собственный метод выглядит следующим образом:
extern "C" {
JNIEXPORT void JNICALL Java_com_test_jnitest_SurfaceRenderer_drawFromJni
(JNIEnv* env, jclass c)
{
//
}
}
с заголовком, заключенным в extern "C" {} aslo.
Все компилируется отлично, создает файл .so и копирует в папку libs в моем проекте, но когда я отлаживаю и запускаю в Eclipse, я продолжаю получать сообщение cat cat о том, что "никакой реализации не найдено для native...". Есть ли что-то, что мне не хватает, поскольку все примеры NDK находятся в C?
Спасибо.
Ответы
Ответ 1
Есть несколько вещей, которые могут привести к "не найденной реализации". Один получает неправильное имя прототипа функции, другое не загружает .so вообще. Вы уверены, что System.loadLibrary()
вызывается до использования метода?
Если у вас нет функции JNI_OnLoad
, вы можете создать ее и вывести сообщение журнала, чтобы убедиться, что lib успешно завершен.
Вы уже уклонились от наиболее распространенной проблемы - забыв использовать extern "C"
- так это либо выше, либо немного неправильной орфографии. Как выглядит выражение Java?
Ответ 2
Дополнительная причина для этой ошибки: ваше имя непринятого родного метода не должно содержать подчеркивания!
Например, я хотел экспортировать функцию C с именем AudioCapture_Ping()
. Вот моя экспортная декларация в C:
JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapture_Ping(JNIEnv *pJniEnv, jobject object); //Notice the underscore before Ping
Вот мой класс Java, импортирующий функцию:
package com.obsidian.mobileaudiohashhost;
...
public class MainActivity extends Activity {
private native int AudioCapture_Ping(); // FAILS
...
Я не мог заставить Android динамически ссылаться на мой собственный метод, пока я не удалю подчеркивание:
JNI_EXPORT int Java_com_obsidian_mobilehashhost_MainActivity_AudioCapturePing(JNIEnv *pJniEnv, jobject object);
package com.obsidian.mobileaudiohashhost;
...
public class MainActivity extends Activity {
private native int AudioCapturePing(); // THIS WORKS!
...
Ответ 3
У меня была такая же проблема, но для меня ошибка была в файле Android.mk. У меня было это:
LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES := B.cpp
но должно иметь следующее:
LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES += B.cpp
обратите внимание на деталь + = вместо : =
Я надеюсь, что это поможет.
Ответ 4
В приложении ndk есть пример cpp:
https://android.googlesource.com/platform/development/+/marshmallow-release/ndk/platforms/android-5/samples/hello-gl2/jni/gl_code.cpp
Ответ 5
Дополнительная причина: используйте LOCAL_WHOLE_STATIC_LIBRARIES вместо LOCAL_STATIC_LIBRARIES в android.mk. Это останавливает библиотеку от оптимизации неиспользуемых вызовов API, потому что NDK не может обнаружить использование собственных привязок из Java-кода.
Ответ 6
Использовать javah (часть Java SDK). Его инструмент точно для этого (генерирует заголовок .h из файла .class).
Ответ 7
Вызывается extern "C", как указано в примере с автоматически созданным Studio, но забыл обернуть весь остальной файл, включая следующие функции, в {} скобках. Работала только первая функция.
Ответ 8
Я пытаюсь выполнить все вышеперечисленные решения, но никто не может решить мою ошибку сборки (jni java.lang.UnsatisfiedLinkError: не реализована реализация для...),
наконец, я обнаружил, что забыл добавить исходный файл verify.cpp в CMakeList.txt add_library segement (verify.cpp автоматически генерируется с помощью Ctrl + Enter short key, возможно, другое имя файла), надеюсь, что мой ответ может помочь кому-то.
моя среда сборки: Gradle + CMake
Ответ 9
I Столкнулась с той же проблемой, и в моем случае причина заключалась в том, что у меня был знак подчеркивания в имени пакета "RFID_Test"
Я переименовал пакет, и он сработал.
Спасибо пользователю1222021