Opencv将Mat从Android传递到JNI错误
Posted
技术标签:
【中文标题】Opencv将Mat从Android传递到JNI错误【英文标题】:Opencv passing Mat from Android to JNI error 【发布时间】:2016-03-29 07:56:01 【问题描述】:我查看了所有内容,但我不明白为什么会收到致命信号 11。
Java端:
mRgba = inputFrame.rgba();
String nativeTesting = mNativeDetector.getFeatures(mRgba);
Log.e(TAG, nativeTesting);
// In another class
public String getFeatures(Mat image)
Log.e("FRAME", " Rows:" +image.rows()); // This correctly returns the number of rows
String resultMsg = nativeFeatures(mNativeObj, image.getNativeObjAddr());
return resultMsg;
C++ 方面:
JNIEXPORT jstring JNICALL Java_com_example_myfacedetection_DetectionBasedTracker_nativeFeatures (JNIEnv* env, jclass, jlong image)
LOGD("NativeFeatures enter");
try
Mat* frame = (Mat*) image;
// if (frame.empty()) // This also results in Fatal Signal
// LOGD("EMPTY FRAME");
LOGD("Size: %d", frame->rows);
catch(cv::Exception& e)
LOGD("nativeCreateObject caught cv::Exception: %s", e.what());
jclass je = env->FindClass("org/opencv/core/CvException");
if(!je)
je = env->FindClass("java/lang/Exception");
env->ThrowNew(je, e.what());
return (env)->NewStringUTF("Hello from JNI !");
我正在尝试计算直方图,但对帧的任何访问都会导致 SegFault。我做错了什么?
【问题讨论】:
您的本机函数只接受一个参数(long
),但您从 Java 代码中传递了两个参数。根据您向我们展示的代码,我看不出您如何没有收到 UnsatisfiedLinkError。
JNI 使用 C 链接(无名称修改),因此链接器只寻找 Java_com_example_myfacedetection_DetectionBasedTracker_nativeFeatures
并找到它就好了。
【参考方案1】:
问题
这里最可能的问题是您在 Java 中的本机方法声明(您没有列出)与 JNI 库中的签名不匹配。
你在叫它:
String resultMsg = nativeFeatures(mNativeObj, image.getNativeObjAddr())
所以你可能有(否则 javac 不会编译):
static native String nativeDetect(long thiz, long image);
但是在你的 JNI 库中你有:
JNIEXPORT jstring JNICALL Java_snip_nativeFeatures (JNIEnv* env, jclass, jlong image)
因此,您将 mNativeObj
传递给 image
,将其转换为 Mat
并在实际尝试跟踪指针时获取 SIGSEGV。
解决方案
要解决此问题,请更新方法签名以匹配。例如,如果您不需要访问实例,请将静态方法设为 nativeDetect(long image)
(并且不要将 mNativeObj
传递给它)。
注意
您有责任确保 Java 和 C/C++ 源文件之间的方法签名匹配。 Unless you have overloaded the native method (two signatures for the same name), the dynamic library loader is only looking for Java_packageName_className_methodName
并且无法判断参数或类型的数量不匹配。
【讨论】:
"你不能重载 JNI 方法。" 当然可以:"对于重载的本机方法,后跟两个下划线(“_”)通过损坏的参数签名“_ (source) 啊,没错,但显然这只适用于方法首先被重载(Java 端)的情况。以上是关于Opencv将Mat从Android传递到JNI错误的主要内容,如果未能解决你的问题,请参考以下文章
将 YUV_420_888 中的图像从 Android 发送到 OpenCV Mat 中的 JNI 的最有效方法