How to pass an ArrayList from Java to native (NDK) in opencv for android
On the Java side I have
List<Mat> arystrdimages = new ArrayList<Mat>();
The images read from folders in the external catalog are then added to the list
for(File f : strdimgs)
{
Mat tempimg = Highgui.imread(f.getAbsolutePath(), CvType.CV_8UC1);
arystrdimages.add(tempimg);
}
On the native jni side, I want to access arystrdimages by reference.
For a single Mat object, we can complete the method by calling getNativeObjAddr
, i.e. in the opencv4android example of the Mat object, the access on the native side is done as follows
Java
private Mat mRgba;
Call native
CallNative(mRgba.getNativeObjAddr());
On the native side
JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial2_Tutorial2Activity_CallNative(JNIEnv *env, jobject thiz, jlong addrRgba1)
{
Mat& mRgb = *(Mat*)addrRgba1;
}
How do I perform this action object for List<Mat>
?
EDIT: Implementation of your suggested solution
Java side
int elems = arystrdimages.size();
Log.v("Matobjdata", "number of Matobject read = " + elems);
Log.v("Matobjdata", "from native = " + ans);
long[] tempobjadr = new long[elems];
for (int i=0; i<elems; i++)
{
Mat tempaddr = arystrdimages.elementAt(i);
tempobjadr[i] = tempaddr.getNativeObjAddr();
}
Log.v("Matobjdata", "addresselementsinlong arrray = " + tempobjadr.length);
int ans = TrainDescriptors(tempobjadr); Call to native function
Log.v("Matobjdata", "from native = " + ans);
Native side
JNIEXPORT jint JNICALL Java_org_opencv_samples_tutorial2_Tutorial2Activity_TrainDescriptors(JNIEnv *env, jobject trainobject, jlongArray traindataaddr)
{
vector<Mat> trainimgs;
jsize a_len = env->GetArrayLength(traindataaddr);
jlong *traindata = env->GetLongArrayElements(traindataaddr, 0);
for(int k=0; k<a_len; k++)
{
Mat & newimage=*(Mat*)traindata[k];
trainimgs.push_back(newimage);
}
Do the required manipulation on the images;
env->ReleaseLongArrayElements(traindataaddr, traindata, 0);
return a_len;
}
Solution
You can build an array of long values (getNativeObjAddr() results for all Mats) in Java and call the native function that passes the array.
In JNI, you can access all long values using GetArrayLength and GetLongArrayElements, which return jlong to the first element.
Use ReleaseLongArrayElements when you’re done.