Как устранить ошибку java.lang.UnsatisfiedLinkError в NDK на Android?

Я новичок в разработке ndk в android. Я прошел через файловую систему 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.

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

Заранее спасибо,


person Indrajit Kumar    schedule 16.07.2010    source источник
comment
Вы уверены, что класс, в котором вы объявили invokeNativeFunction(), на самом деле является com.mindtherobot.samples.ndkfoo.NdkFooActivity? Вы можете опубликовать весь код   -  person ognian    schedule 17.07.2010
comment
В частности, включите объявление собственного метода в файл .java. Покажите также объявления пакетов и классов. Кроме того, добавьте функцию JNI_OnLoad в свою общую библиотеку и поместите туда журнал, чтобы вы могли убедиться, что библиотека загружается успешно.   -  person fadden    schedule 19.07.2010
comment
Проверьте это объявление в ndkfoo.c Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction, оно должно измениться на имя вашего пакета, например Java_com_your_package_ndkfoo_NdkFooActivity_invokeNativeFunction.   -  person pradeep    schedule 30.04.2011


Ответы (12)


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

Java_com_mindtherobot_samples_ndkfoo

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

person StarDust    schedule 09.03.2011

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

person Daniel Rodriguez    schedule 13.12.2012
comment
@Daniel Rodriguez: Большое спасибо. :) :) :) :) - person Bhavesh Patadiya; 13.07.2013
comment
Попробуйте ошибку. Было потеряно много часов отладки, чтобы дать вам этот ответ. - person Daniel Rodriguez; 14.11.2013
comment
... если загружаемая вами библиотека не была скомпилирована для x86 - person CCJ; 18.02.2014
comment
Также стоит отметить, что эту проблему можно решить путем компиляции для всех архитектур, как показано на stackoverflow.com/a/12607739/2264920 - person 2013Asker; 08.03.2014
comment
Как узнать, является ли эмулятор Intel Atom x86 или обычным эмулятором? - person Yirga; 20.12.2016

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

static {
    System.loadLibrary("mylibraryname");
}
person 18446744073709551615    schedule 20.01.2012
comment
обычно это вызывает следующую проблему: «java.lang.ExceptionInInitializerError java.lang.UnsatisfiedLinkError: Library xyz... not found» - person ademar111190; 13.11.2012

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

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

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

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

person SomeCallMeTim    schedule 25.09.2010
comment
Спасибо. В моей системе его нужно запускать из подкаталога Classes. - person weston; 04.09.2012

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

person Elis Popescu    schedule 11.12.2012

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

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

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

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

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

общедоступная статическая нативная строка invokeNativeFunction();

person Justin Buser    schedule 13.01.2012

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, и поместите в него что-то из этого:

  1. APP_ABI := x86
  2. APP_ABI := армеаби
  3. APP_ABI := мили в секунду
  4. APP_ABI := armeabi x86 mips //для компиляции во все цели, и вы получите 3 файла *.so

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

person SRedouane    schedule 11.08.2013

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

APP_ABI := armeabi armeabi-v7a

person Sajal Saha    schedule 25.11.2012

Имя метода 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.

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

person Jagdeep Singh    schedule 11.06.2013

Замените это

Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction

С участием

Java_your_packege_name_your_Activity_Name_invokeNativeFunction

Пример, если ваш пакет com.pack, а имя действия — MainActivity, тогда

Java_com_pack1_MainActivity_invokeNativeFunction 

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

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

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

 public native String invokeNativeFunction();

Повторите все эти шаги, это должно сработать :)

person Vinayak    schedule 28.07.2013

У меня также была ошибка 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 ‹- работает

person Awesomeness    schedule 29.03.2013