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

Как разрешить java.lang.UnsatisfiedLinkError в NDK на Android?

Я новичок в разработке ndk в android.I прошел файловую систему ndk android. Здесь, объясняя, что я сделал. 1) я создал папку с именем "jni", затем создаю 2 файла с именем Android.mk и ndkfoo.c.

В Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# Here we give our module name and source file(s)
LOCAL_MODULE    := ndkfoo
LOCAL_SRC_FILES := ndkfoo.c

include $(BUILD_SHARED_LIBRARY)

и в ndkfoo.c

#include <string.h>
#include <jni.h>

jstring Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
 return (*env)->NewStringUTF(env, "Hello from native code!");
}

то я создал класс NdkFooActivity, в котором я написал

// load the library - name matches jni/Android.mk
 static {
  System.loadLibrary("ndkfoo");
 }

Но теперь, когда я строю из cygwin в xp, он создает .so файл успешно, тогда я запускаю приложение для Android. Это дает мне java.lang.UnsatisfiedLinkError в LOGCAT.

Итак, пожалуйста, дайте мне знать, где я ошибаюсь.

Спасибо, Advance,

4b9b3361

Ответ 1

Я думаю, вы забыли изменить имя пакета.

Java_com_mindtherobot_samples_ndkfoo

Это должен быть ваш пакет, который вы указали для создания проекта.

Ответ 2

Также (просто столкнулся с этой проблемой), обратите внимание, что System.loadLibrary() всегда будет генерировать исключение, если вы тестируете эмулятор Intel Atom x86. Он отлично работает на обычных эмуляторах Android и отлаживается на физическом устройстве.

Ответ 3

Хотя это не проблема OP, у меня был тот же java.lang.UnsatisfiedLinkError из-за отсутствия

static {
    System.loadLibrary("mylibraryname");
}

Ответ 4

Там хороший шанс, что подпись неверна, как упомянули другие.

Если вы запустите утилиту javah, вы можете найти точную подпись. Из папки bin в вашем проекте, где находится .apk и корень иерархии классов Java, запустите:

javah -o jni_sig.h com.mindtherobot.whatever.your.package.is.NdkFooActivity

... и если вы правильно назвали имя пакета и имя класса, он будет выписывать заголовок (называемый jni_sig.h) с правильной сигнатурой функции для любых нативных функций. Скопируйте это в свой заголовок и .c файл, добавив параметры по мере необходимости, и он должен работать правильно.

Ответ 5

Возможно, это уже не актуально, но насколько я знаю, вам также нужно добавить префикс "lib" к имени вашей родной библиотеки. В вашем случае вам нужно изменить Android.mk на "LOCAL_MODULE: = libndkfoo" и сохраните "System.loadLibrary(" ndkfoo "); как есть. Проверьте код образца ndk.

Ответ 6

Я уверен, что это должно быть:

JNIEXPORT jstring JNICALL Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
 return (*env)->NewStringUTF(env, "Hello from native code!");
}

Какой SDK вы нацеливаете и какая версия NDK у вас есть? Получается ли ошибка, которую вы получаете, говорит, что она не может загрузить библиотеку вообще или что существует нереализованный метод? В любом случае убедитесь, что у вас нет андроида: hasCode = "false", установленный в теге приложения в манифесте.

Вы также можете открыть файл APK после сборки с помощью winrar или что-то подобное, чтобы убедиться, что файл libndkfoo.so действительно включен в пакет.

В любом случае, если вы не объявляете собственную функцию в NdkFooActivity, вы получите эту ошибку, т.е.

public static native String invokeNativeFunction();

Ответ 7

JNIEXPORT jstring JNICALL Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {
 return (*env)->NewStringUTF(env, "Hello from native code!");
}

проблема заключается в том, что вы компилируете для целевого процессора и выполняете в другом. если вы компилируете в ARM (armeabi), то выполняйте в эмуляторе на основе armeabi. создайте файл под названием application.mk в той же папке, что и Android.mk, и поместите внутри него один из следующих:

  • APP_ABI: = x86
  • APP_ABI: = armeabi
  • APP_ABI: = mips
  • APP_ABI: = armeabi x86 mips//компилировать во всех целях, и вы получите 3 *.so файлы

затем выполните компиляцию- > выполнить. он должен работать.

Ответ 8

Создайте файл Application.mk в jni-папке. Скопируйте следующую строку и вставьте ее в Application.mk и сохраните. Теперь создайте проект с помощью cgywin и снова запустите.

APP_ABI: = armeabi armeabi-v7a

Ответ 9

Имя метода Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction

может быть не таким же, как имя вашего пакета или имя класса. Чтобы сделать это наименование метода точно таким же, вы должны использовать javah.

Это сделает заголовочный файл, который будет иметь то же самое имя метода, которое требуется. Чтобы этот заголовочный файл перейти в папку классов в корзине вашего проекта (убедитесь, что вы создали java файл со статическим методом и постройте его правильно) с помощью этой команды в терминале

~/workspace/Android_Example2/bin/classes$

В этом каталоге введите следующую команду

sudo javah -jni com.NDK.android_example2.MainActivity

Измените имя пакета и имя класса в соответствии с вашим проектом. Это создаст com_NDK_android_example2_MainActivity.h в вашей папке классов.

Просто переместите этот файл в папку jni. В этом файле будут созданы статические методы, которые вы создали в файле MainActivity.java, но они просто объявлены не реализованы, которые будут реализованы в вашем файле C.

ПРИМЕЧАНИЕ. При копировании метода проверьте, должны ли быть объявлены параметры метода, поэтому объявите их в файле C.

Надеюсь на эту помощь.

Ответ 10

У меня также была ошибка java.lang.UnsatisfiedLinkError. Я подтвердил все упоминания в ответах выше, но все еще получал ошибку. В конце концов я обнаружил, что имена методов JNI не могут иметь подчеркивания.

Пример: Java_com_example_app_NativeLib_print_out_stuff < - генерирует java.lang.UnsatisfiedLinkError: print_out_stuff

Переименуйте функцию print_out_stuff на что-то без подчеркивания: Java_com_example_app_NativeLib_printOutStuff < - works

Ответ 11

здесь учебник, как использовать собственный код: здесь

убедитесь, что у вас нет пробелов в пути к проекту. также вы не можете использовать подчеркивание в своем пакете или имени проекта.

Ответ 12

Замените это

Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction

С

Java_your_packege_name_your_Activity_Name_invokeNativeFunction

Пример, если ваш пакет является com.pack, а имя Activity Name - MainActivity, затем

Java_com_pack1_MainActivity_invokeNativeFunction 

Не забудьте добавить ссылку в действие.

//загружать библиотеку - имя соответствует jni/Android.mk

static {
        System.loadLibrary("ndkfoo");
      }

 public native String invokeNativeFunction();

Повторите все эти шаги, чтобы они работали:)