pww*_*che 8 java-native-interface android opencv
我正在使用OpenCV开发一个Android项目.有些方法没有Java版本,所以我必须使用NDK在我的项目中使用它们.
这是我第一次使用NDK,所以在搜索了一些例子之后,我编写了我的代码,在我的设备上运行它,并收到以下错误消息:
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)
Run Code Online (Sandbox Code Playgroud)
我多次重新生成.so文件,并检查jni函数的命名.我还为jni函数添加了'extern"C"'包装器.但这些解决方案都没有奏效.
注意:我总是使用Intellij Idea来开发JAVA程序,因为Idea不支持NDK,我必须使用Eclipse来访问NDK,所以...这也是我第一次使用Eclipse.我本可以犯很多愚蠢的错误.大声笑
下面是我的c ++代码和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();
}
Run Code Online (Sandbox Code Playgroud)
LocalFeatures.h和LocalFeatures.cpp没有显示,但我确定问题不在于它们.
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)
Run Code Online (Sandbox Code Playgroud)
那些.cpp文件和.mk文件位于Eclipse项目中.libmytest_lib.so,libopencv_java.so,libnonfree.so可以正确生成.以下.java文件位于Intellij Idea项目中.我已将这些.so文件复制到Idea项目中的\ lib.
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();
}
Run Code Online (Sandbox Code Playgroud)
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*/
}
Run Code Online (Sandbox Code Playgroud)
非常感谢!
按照JonesV的建议,我从代码中删除了静态.但在那之后,问题仍然存在.
最后我调试了我的程序,当运行到这一行时:
System.loadLibrary("opencv_java");
Run Code Online (Sandbox Code Playgroud)
该程序引发了错误,而不是像我想象的那样正常运行.真正愚蠢的错误:<
现在我发现了一个我以前从未注意到的错误.
java.lang.UnsatisfiedLinkError: Couldn't load opencv_java: findLibrary returned null
Run Code Online (Sandbox Code Playgroud)
这意味着,没有负载.所以我检查了我的项目结构,发现我把我的.so文件放在libs /文件夹中,而不是libs/armeabi /文件夹.
解决方案在这里找到: Android NDK java.lang.UnsatisfiedLinkError:findLibrary返回null
I added
extern "C"
Run Code Online (Sandbox Code Playgroud)
before functions declare ex:
extern "C"
jstring
Java_lara_myapplication_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
Run Code Online (Sandbox Code Playgroud)
then the error was gone
| 归档时间: |
|
| 查看次数: |
27870 次 |
| 最近记录: |