java - 使用 CallVoidMethod 将 mat 数组从 native 代码传递到 java 代码

标签 java arrays java-native-interface native mat

我想传递从 Java 类中的 native 方法计算的数组数组。为此,我想从 native 代码调用方法 setTarghet 来设置每个 vector 场。我认为这是个好主意。 这是一个 Java 类:

public class struttura {


 private int _facetCount;


    public Mat [] VectorTarget;

    public struttura(int facetCount)
    {
        _facetCount = facetCount;


        VectorTarget = new Mat[facetCount];

    }

    public int getFacetCount()
    {
        return _facetCount;
    }

    public void setTarget (int index,Mat value)
    {
        VectorTarget[index]=value;    

    }
}

这是本地代码

 JNIEXPORT void JNICALL Java_com_example_nonfreejnidemo_NonfreeJNILib_extractorSuTarget(JNIEnv * env, jobject obj, jint nT )
{
   .....

    Mat object[50];

  // read 50 image and put them in object[i]
        for (unsigned int i = 0;i < 50 ;i++) {
            object[i] = imread( files[i], CV_LOAD_IMAGE_GRAYSCALE );
        }

        //Detect the keypoints using SURF Detector
        int minHessian = 500;

        SurfFeatureDetector detector( minHessian );
        std::vector<KeyPoint> kp_object[nT];


        for (unsigned int i = 0;i < nT; i++)
        {
            detector.detect( object[i], kp_object[i] );
        }


        //Calculate descriptors (feature vectors)
        SurfDescriptorExtractor extractor;

        Mat des_object[nT];

        for (unsigned int i = 0;i < nT; i++)
        {
             extractor.compute( object[i], kp_object[i], des_object[i] );

        }
        //-----------------------------------------------------------------------------------------------
        // now begin my problem
    // i want to call method setTarget from java code to map des_object on VectorTarget 
    // and use it on java code.
    // i try something like this but i have some  errors.
    // i now that it is not correct, i do not know how write it.

    for (int index=0; index <50; index++)
    {

               jlong        y  =    (jlong)des_object[index] ;
               jclass cls = env->GetObjectClass(obj);
               jmethodID methodId = env->GetMethodID( cls, "setTarget", "(IJ)V");
               env->CallVoidMethod(obj, methodId,index,y );

     }
        //-----------------------------------------------------------------------------------------------

我想从 java 代码调用方法 setTarget 以将 des_object 映射到 VectorTarget 并在 java 代码上使用它。 我尝试这样的事情,但我有一些错误。 我知道它不正确,我不知道怎么写 请帮助我。

最佳答案

您的概念有一个流程 - 您不能将类 Mat 的 C++ 实例作为类 Mat 的 Java 对象传递。

另一方面,您不需要调用 Java 方法来设置 Java 对象数组的元素。

所以,你的循环可以简单地看起来像

jclass matClass = static_cast<jclass>(env->FindClass("com/example/Mat");
jmethodID matConstructor = env->GetMethodID(matClass, "<init>", "([I)V");
for (int index=0; index<50; index++)
{
    jobject jMatObject = env->NewObject(matClass, matConstructor, des_object[index]);
    env->SetObjectArrayElement( arr, i, jMatObject);
    env->DeleteLocalRef(jMatObject);
}

如果您的描述符不是一个整数数组,您必须为您的 Mat Java 类准备相关的构造函数。

请注意,对于 extractorSuTarget() native 方法的所有调用,您可以缓存 matClassmatConstructor .


如果您不需要访问 des_object 的各个元素,您的生活就容易多了:

public class struttura {

    private int _facetCount;

    public long nativeVectorTarget;

    public struttura(int facetCount)
    {
        _facetCount = facetCount;
    }

    public int getFacetCount()
    {
        return _facetCount;
    }

    private void setTarget(long nativePointer)
    {
        nativeVectorTarget = nativePointer;

    }
}

在 C++ 中,

extern "C" JNIEXPORT void JNICALL Java_com_example_nonfreejnidemo_NonfreeJNILib_extractorSuTarget(JNIEnv * env, jobject obj, jint nT )
{
   .....

    Mat object[50];

  // read 50 image and put them in object[i]
        for (unsigned int i = 0;i < 50 ;i++) {
            object[i] = imread( files[i], CV_LOAD_IMAGE_GRAYSCALE );
        }

        //Detect the keypoints using SURF Detector
        int minHessian = 500;

        SurfFeatureDetector detector( minHessian );
        std::vector<KeyPoint> kp_object[nT];


        for (unsigned int i = 0;i < nT; i++)
        {
            detector.detect( object[i], kp_object[i] );
        }

        //Calculate descriptors (feature vectors)
        SurfDescriptorExtractor extractor;

        Mat* des_object = new Mat[nT]();

        for (unsigned int i = 0;i < nT; i++)
        {
             extractor.compute( object[i], kp_object[i], des_object[i] );

        }
        jclass cls = env->GetObjectClass(obj);
        jmethodID methodId = env->GetMethodID( cls, "setTarget", "(J)V");
        env->CallVoidMethod(obj, methodId, (jlong)des_object);

}

关于java - 使用 CallVoidMethod 将 mat 数组从 native 代码传递到 java 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30281875/

相关文章:

java - 一般使用 java JNI GetFieldID 和 JNI

android - 32 bpp 单色位图转 1 bpp TIFF

java - FieldUndefined 类型的验证错误 : Field 'register' in type 'Query' is undefined

arrays - 带有 Fortran 假定大小数组的 JNA

c++ - 简单数组不能正常工作

java - 如何释放字符**

java - Java错误: Cannot find symbol (acm)

java - 创建带有 FileDescriptor 的 FileReader 有何用处?

java - 一旦执行异步任务任务,变量就会丢失数据

arrays - 对三个数组的元素进行排序的算法