Android NDK C++ JNI (не найдено реализации для native…)


Я пытаюсь использовать NDK с C++ и, похоже, не могу получить правильное соглашение об именовании методов. мой родной метод заключается в следующем:

extern "C" {
JNIEXPORT void JNICALL Java_com_test_jnitest_SurfaceRenderer_drawFromJni
(JNIEnv* env, jclass c)
{
   //
}
}

с заголовком, завернутым в extern" C " {} также.

все компилируется нормально, создает файл. so и копирует в папку libs под моим проектом, но когда я отлаживаю и запускаю в Eclipse, я продолжаю получать сообщение журнала cat о том, что "нет реализации для native...". Есть ли что-то, что мне не хватает, как и все примеры NDK в Си?

спасибо.

11 63

11 ответов:

есть несколько вещей, которые могут привести к "нет реализации". Один получает имя прототипа функции неправильно, другой не может загрузить .so вообще. Вы уверены, что System.loadLibrary() вызывается, прежде чем использовать этот метод?

Если у вас нет JNI_OnLoad функция определена, вы можете создать ее и выплюнуть сообщение журнала, чтобы убедиться, что lib успешно втягивается.

вы уже уклонились от самой распространенной проблемы -- забыв использовать extern "C" -- Так что это либо выше, либо некоторые небольшие ошибки в написании. Как выглядит объявление Java?

дополнительная причина этой ошибки: ваше имя собственного метода не должно содержать подчеркивания!

например, я хотел экспортировать функцию 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!
    ...

у меня была та же проблема, но для меня ошибка была в файле Android.mk. у меня это было:

LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES := B.cpp 

но должно быть так:

LOCAL_SRC_FILES := A.cpp
LOCAL_SRC_FILES += B.cpp 

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

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

вызывается extern "C", как указано в автоматически сгенерированном примере Studio, но забыл обернуть всю остальную часть файла, включая следующие функции, в {} скобки. Работала только первая функция.

дополнительная причина: используйте LOCAL_WHOLE_STATIC_LIBRARIES вместо LOCAL_STATIC_LIBRARIES в android.mk это останавливает библиотеку от оптимизации неиспользуемых вызовов API, потому что NDK не может обнаружить использование собственных Привязок из кода java.

используйте javah (часть Java SDK). Его инструмент именно для этого (генерирует .h заголовок от .файл класса.)

Я пробую все вышеперечисленные решения, но никто не может решить мою ошибку сборки(JNI java.ленг.UnsatisfiedLinkError: реализация не найдена...), наконец я обнаружил, что забыл добавить свою проверку.исходный файл cpp в CMakeList.txt add_library segement (verify.cpp автоматически генерируется с помощью Ctrl + Enter short key, возможно, другое имя файла), надеюсь, что мой ответ может помочь кому-то.

моя среда сборки: Gradle + CMake

Я столкнулся с той же проблемой, и в моем случае причиной было то, что у меня было подчеркивание в имени пакета " RFID_Test" Я переименовал пакет, и это сработало. Спасибо user1222021

Если ваше имя пакета включает _ символ, вы должны написать 1 (один) после _ символа, как показано ниже:

MainActivity.java

package com.example.testcpp_2;

native-lib.cpp

JNICALL
Java_com_example_testcpp_12_MainActivity_stringFromJNI(

Я столкнулся с той же проблемой дважды. Так получилось, что телефон, который я пытался запустить приложение из Android Studio, использовал уровень API что я еще не скачал в Android Studio.

  1. обновление Android Studio до последней версии
  2. загрузите необходимый API из Android Studio