Pracuję nad projektem Android przy użyciu OpenCV. Niektóre metody nie mają wersji Java, więc muszę użyć NDK, aby użyć ich w moim projekcie.JNI- java.lang.UnsatisfiedLinkError: Natywna metoda nie została znaleziona
To jest mój pierwszy raz przy użyciu NDK, więc po wyszukaniu niektórych przykładach, napisałem mój kod, uruchom go w urządzeniu i otrzymał komunikat o błędzie poniżej:
07-04 10:26:19.555 21270-21270/com.example.MyTest E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.UnsatisfiedLinkError: Native method not found: com.example.MyTest.JNIlib.readImg:()I
at com.example.MyTest.JNIlib.readImg(Native Method)
at com.example.MyTest.MyActivity$2.onClick(MyActivity.java:60)
at android.view.View.performClick(View.java:4211)
at android.view.View$PerformClick.run(View.java:17267)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4898)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
at dalvik.system.NativeStart.main(Native Method)
I zregenerowany .so plików na kilka razy i sprawdź nazewnictwo funkcji jni. Dodałem także "zewnętrzne" C "" opakowania do funkcji jni. Ale żadne z tych rozwiązań nie zadziałało.
Uwaga: Zawsze używam Intellij Idea do tworzenia programów JAVA, a ponieważ Idea nie obsługuje NDK, a ja muszę korzystać z Eclipse, aby dostać się do NDK, więc ... to jest także pierwszy raz, kiedy używam Eclipse. Mogłem popełnić wiele głupich błędów. lol
Poniżej znajdują się moje kody C++ i plik Makefile.
LocalMain.cpp
#include <stdio.h>
#include <iostream>
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/opencv.hpp>
#include <jni.h>
#include <android/log.h>
#include "LocalFeature.h"
using namespace cv;
using namespace std;
int readImg()
{
/* do something*/
return 0;
}
// JNI interface functions, be careful about the naming.
extern "C"
{
JNIEXPORT jint JNICALL Java_com_example_MyTest_JNIlib_readImg(JNIEnv * env, jobject obj);
};
JNIEXPORT jint JNICALL Java_com_example_MyTest_JNIlib_readImg(JNIEnv * env, jobject obj)
{
return (jint)readImg();
}
LocalFeatures.h i LocalFeatures.cpp nie są pokazane, ale jestem pewien, że problem nie jest z nimi.
Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := nonfree_prebuilt
LOCAL_SRC_FILES := libnonfree.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := opencv_java_prebuilt
LOCAL_SRC_FILES := libopencv_java.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
# Modify LOCAL_C_INCLUDES with your path to OpenCV for Android.
LOCAL_C_INCLUDES:= E:/Java/libs/OpenCV-2.4.9-android-sdk/sdk/native/jni/include
LOCAL_MODULE := mytest_lib
LOCAL_CFLAGS := -Werror -O3 -ffast-math
LOCAL_LDLIBS += -llog -ldl
LOCAL_SHARED_LIBRARIES := nonfree_prebuilt opencv_java_prebuilt
LOCAL_SRC_FILES := LocalMain.cpp \
LocalFeature.h \
LocalFeature.cpp
include $(BUILD_SHARED_LIBRARY)
te pliki .cpp i pliki .mk są w ramach projektu Eclipse. libmytest_lib.so, libopencv_java.so, libnonfree.so może być poprawnie wygenerowany. Następujące pliki .java znajdują się w projekcie Intellij Idea. Skopiowałem te pliki .so do \ lib w projekcie Idea.
JNIlib.java
public class JNIlib {
static
{
try
{
// Load necessary libraries.
System.loadLibrary("opencv_java");
System.loadLibrary("nonfree");
System.loadLibrary("mytest_lib");
}
catch(UnsatisfiedLinkError e)
{
System.err.println("Native code library error.\n");
}
}
public static native int readImg();
}
Część MainActivity.java
public class MyActivity extends Activity implements CameraBridgeViewBase.CvCameraViewListener2{
public View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
JNIlib.readImg();
}
};
/*Other irrevelant code*/
}
Dzięki wielkie!
Jesteś tak w połowie mojego problemu, i pozwolę sobie uświadomić, że problem dotyczy nie tylko mojego kodu, ale także mojej struktury projektu. Dzięki :) – pwwpche
Właściwie to nie ma znaczenia. 'JNIEXPORT jint JNICALL Java_com_example_MyTest_JNIlib_readImg (JNIEnv * env, jobject obj)' i 'JNIEXPORT jint JNICALL Java_com_example_MyTest_JNIlib_readImg (JNIEnv * env, jclass obj)', ponieważ w C, ** jclass ** i ** jobject ** są synonimami. –
@SteveM możesz rozwinąć? 'static' ukrywa metodę na wszystkich urządzeniach, podczas gdy ** jobject ** jest tylko' void * ', gdy jest używane poprawnie. –