使用CallVoidMethod将本地代码的mat数组传递给java代码

时间:2015-05-16 23:48:45

标签: java arrays java-native-interface native mat

我想传递一个从Java类中的本机方法计算的数组数组。为此,我想从本机代码调用方法setTarghet来设置每个向量字段。我认为这是一个好主意。 这是一个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来映射VectorTarget上的des_object并在java代码上使用它。 我尝试这样的东西,但我有一些错误。 我知道这不正确,我不知道怎么写 请帮帮我。

1 个答案:

答案 0 :(得分:1)

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

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

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

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()原生方法的所有调用,您都可以缓存 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);

}