尝试在创建新对象时将参数提供给JNI对象的构造函数时出错

时间:2019-03-06 14:17:57

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

我正在使用NDK,CPP,Opencv和Java开发一个Android应用程序。所以,这里我得到了错误。我需要使用JNI方法将ArrayOf Mat对象从CPP传递到Java。我的代码如下。

jclass thisclass = env->GetObjectClass(instance);
jclass matclass = env->FindClass("org/opencv/core/Mat");
if (env->ExceptionOccurred())
    return NULL;

const char* constructorSignature = "(Lorg/opencv/core/Mat;Lorg/opencv/core/Rect;)V";
jmethodID constructor = env->GetMethodID(matclass, "<init>", constructorSignature);
if (env->ExceptionOccurred())
        return NULL;

如上所示,我有Mat类,然后通过提供Mat和Rect作为参数为Mat类创建了构造函数签名,因为Mat类中有一个构造函数接受Mat和Rect作为输入并创建Mat作为回报。

但是在创建构造函数后,当我尝试使用该构造函数创建对象时,我遇到了错误。

std::vector<Mat> selectedMats;
std::vector<Rect> selectedRects;
for(int h = 0; h < selectedRects.size(); h++){


        ls = &(selectedMats[h]);
        lsRect = &multiRectToCropOriginal;
        __android_log_print(ANDROID_LOG_ERROR, "TRACKERS", "%ld", (long)ls);
        // create new object
        jobject matObject = (jobject)env->NewObject(matclass, constructor, ls, lsRect);

        // put object into array
        env->SetObjectArrayElement(matArray , h, matObject);


    }

selectedMats是Mat的向量,我已创建Mat并将其分配了数据。

在应用程序中遇到像JNI DETECTED ERROR这样的错误:使用无效的jobject 0xa32788f8

传递ls和lsRect时。

现在,当我将Mat和Rect作为对象传递时,它甚至不会编译,并给出如下所述的错误。

代码->

更改为
jobject matObject = (jobject)env->NewObject(matclass, constructor, *ls, *lsRect);

Build command failed.
Error while executing process /home/karshsoni/Android/Sdk/cmake/3.6.4111459/bin/cmake with arguments {--build /home/karshsoni/Documents/CVTextDetection/app/.externalNativeBuild/cmake/debug/armeabi-v7a --target native-lib}
[1/2] Building CXX object CMakeFiles/native-lib.dir/native-lib.cpp.o
FAILED: /home/karshsoni/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++  --target=armv7-none-linux-androideabi21 --gcc-toolchain=/home/karshsoni/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64 --sysroot=/home/karshsoni/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/sysroot  -Dnative_lib_EXPORTS -I/home/karshsoni/Downloads/OpenCV/opencv-4.0.1-android-sdk/OpenCV-android-sdk/sdk/native/jni/include -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mfpu=vfpv3-d16 -fno-addrsig -march=armv7-a -mthumb -Wa,--noexecstack -Wformat -Werror=format-security -stdlib=libc++  -std=gnu++11 -O0 -fno-limit-debug-info  -fPIC   -std=gnu++11 -MD -MT CMakeFiles/native-lib.dir/native-lib.cpp.o -MF CMakeFiles/native-lib.dir/native-lib.cpp.o.d -o CMakeFiles/native-lib.dir/native-lib.cpp.o -c /home/karshsoni/Documents/CVTextDetection/app/src/main/cpp/native-lib.cpp
/home/karshsoni/Documents/CVTextDetection/app/src/main/cpp/native-lib.cpp:268:76: error: cannot pass object of non-trivial type 'cv::Mat' through variadic method; call will abort at runtime [-Wnon-pod-varargs]
        jobject matObject = (jobject)env->NewObject(matclass, constructor, ls, lsRect);
                                                                           ^
/home/karshsoni/Documents/CVTextDetection/app/src/main/cpp/native-lib.cpp:268:81: error: cannot pass object of non-trivial type 'cv::Rect' (aka 'Rect_<int>') through variadic method; call will abort at runtime [-Wnon-pod-varargs]
        jobject matObject = (jobject)env->NewObject(matclass, constructor, ls, lsRect);
                                                                                ^
2 errors generated.
ninja: build stopped: subcommand failed.

如果对此有任何想法或发现任何关于此的谢谢错误。

1 个答案:

答案 0 :(得分:1)

您尝试创建Mat对象的过程会将指向两个C ++对象的指针传递给Java C ++对象。有问题的陈述是:

jobject matObject = (jobject)env->NewObject(matclass, constructor, ls, lsRect);

您需要使用env-> NewObject来创建另一个Mat工作对象和Rect工作对象,而不是传递指针ls和lsRect;然后将这些工作对象传递给您对NewObject的原始调用。

您还需要设置Mat and Rect对象的字段。为此,您必须获取它们的字段ID(请参见this StackOverflow答案),并使用JNI函数(如SetIntField,SetDoubleField等)。

这非常复杂,我建议您获得圣亮的《 Java本机接口》的副本,这对我非常有帮助。