0

I am new to opencv with android. I want to get back an array of Mat objects from JNI. I have created an application that sends some Mat objects from java to JNI. I can return int,long and other types from JNI. How would i return Mat object or array of Mat objects? In this example it returns a long object

 JNIEXPORT jlong JNICALL
 Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject
       (JNIEnv *, jclass, jstring, jint);
5
  • 1
    Why are you using JNI? Doesn't opencv already have Java bindings? Commented May 17, 2017 at 21:12
  • @JornVernee cause i want to create Native app with C++ Commented May 17, 2017 at 21:20
  • In JNI everything boils Down to C, and in C you have pointers, So send Mat object you need to send pointer of that Mat object, which would be cast to Mat on java side. Commented May 18, 2017 at 5:01
  • @ZdaR please explain it or give example Commented May 18, 2017 at 7:27
  • 1
    @ZdaR, on the C side your of course can work with pointers, but return Java object you can only via JVM API calls, i.e. you need to bind returnable object to JVM (except primitive types, not arrays). You can't to use C pointers on Java side becouse of you not have directly access to memory. Commented May 18, 2017 at 7:59

1 Answer 1

2

On java side you need to define native method like this:

public class DetectionBasedTracker {

    public static native Mat[] nativeCreateObject(String name, int count);
}

Your need to take information about Mat object from java and return new object as jobject and return array as jobjectArray:

JNIEXPORT jobjectArray JNICALL
Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject
(JNIEnv *env, jclass cls, jstring str, jint count){

    // cls argument - is DetectionBasedTracker.class

    // take class info
    jclass matCls = env->FindClass("your/package/Mat");
    if (env->ExceptionOccurred())
        return NULL;

    // take constructor by signature
    const char* constructorSignature = "(Ljava/lang/String;)V";
    jmethodID constructor = env->GetMethodID(matCls, "<init>", constructorSignature);
    if (env->ExceptionOccurred())
        return NULL;

    // create java objects array
    jobjectArray matArray = env->NewObjectArray((jsize)count, matCls, NULL);
    for(jsize i = 0; i < count; i++){
        // create new object
        jobject mat = env->NewObject(matCls, constructor, /* constructor args */ str);
        // put object into array
        env->SetObjectArrayElement(matArray , i, mat);
    }

    return matArray;
}

To learn more about constructorSignature arguments look at Java VM Type Signatures tabel

Note: this is just a sample of creating Java objects via JNI. Using JNI only for creating instances of java objects - it's a bad practice.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks but how to access this jobject Array in java side
@Sophia, I wrote Java definition for JNI method. You can call it like other Java methods

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.