Opencv将Mat从Android传递到JNI错误

时间:2016-03-29 07:56:02

标签: java android c++ opencv java-native-interface

我查了一切,但我不明白为什么会收到致命信号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。我做错了什么?

1 个答案:

答案 0 :(得分: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}并且无法判断参数或类型的数量是否不匹配。