Подтвердить что ты не робот

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?

Спасибо.

4b9b3361

Ответ 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 

обратите внимание на деталь + = вместо : =

Я надеюсь, что это поможет.

Ответ 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