Android NDK C ++ JNI (реализация не найдена для родного ...) - PullRequest
77 голосов
/ 04 февраля 2010

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

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

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

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

Спасибо.

Ответы [ 11 ]

120 голосов
/ 20 марта 2010

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

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

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

17 голосов
/ 07 февраля 2014

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

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

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

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

, но должно иметь это:

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

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

Надеюсь, это поможет.

5 голосов
/ 14 июля 2017

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

3 голосов
/ 01 октября 2013

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

3 голосов
/ 05 февраля 2010
2 голосов
/ 09 марта 2018

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

MainActivity.java

package com.example.testcpp_2;

native-lib.cpp

JNICALL
Java_com_example_testcpp_12_MainActivity_stringFromJNI(
2 голосов
/ 03 августа 2011

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

1 голос
/ 15 августа 2017

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

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

0 голосов
/ 29 августа 2018

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

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