Android NDK C++ JNI (реализация не найдена для нативных...)

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

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

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

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

Благодарю.

11 ответов

Решение

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

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

Вы уже избежали самой распространенной проблемы - забыли использовать 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.

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

MainActivity.java

package com.example.testcpp_2;

нативной lib.cpp

JNICALL
Java_com_example_testcpp_12_MainActivity_stringFromJNI(

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

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

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

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

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

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