Passing complex data with JNI

Hi all,

I need to transfer a lot of data from c++ to java.
I already used jni but only for simple data like int, bool, string and so on but now,
I need to find a way to pass a vector with custom structs in it to java.

Struct has Name, Email, Score and so on.

Does anyone have a good starting point/solution? Maybe I need to make a json string of it and pass it like that?
Any help is really appreciated.

friendly regards

You can first define a class in java contains member variables you need.
And implements constructor or setter methods to set those variables.

Then, you just new an object in your jni code, use reflection to call setter methods.
Finally, pass that object back to java if you need to (or whatever you want to do with that object)

Splash Huang wrote:

You can first define a class in java contains member variables you need.
And implements constructor or setter methods to set those variables.
>
Then, you just new an object in your jni code, use reflection to call setter methods.
Finally, pass that object back to java if you need to (or whatever you want to do with that object)

And if I want to pass a vector/list/array of custom structs to java?

I just write a simple example for you.
This jni code pass a MyVector object to java side.
(MyVector is a java class)

package com.spastudio.jni.test;

import android.util.Log;

public class MyVector
{
    public int x;
    public int y;
    public String message;

    public MyVector(int x, int y, String message)
    {
        this.x = x;
        this.y = y;
        this.message = message;
    }

    public void print()
    {
        Log.d("MyVector", String.format("x = %d, y = %d, message = \"%s\"", x, y, message));
    }
}

jni code:

#include "android/jni/JniHelper.h"

extern "C"
{
void jni_test(int x, int y, const char *pszMessage)
{
    cocos2d::JniMethodInfo t;

    // we need env to do things so get it from here. (cocos2d-x does not export getEnv function)
    if (cocos2d::JniHelper::getStaticMethodInfo(t, "com/spastudio/jni/test/MainActivity", "printVector", "(Lcom/spastudio/jni/test/MyVector;)V"))
    {
        // get class id of MyVector class
        jclass j_cMyVector = t.env->FindClass("com/spastudio/jni/test/MyVector");

        //  is special for constructor
        jmethodID j_mMyVector = t.env->GetMethodID(j_cMyVector, "", "(IILjava/lang/String;)V");

        // create a jstring from c-string
        jstring j_sMessage = t.env->NewStringUTF(pszMessage);

        // create a MyVector object
        jobject j_oMyVector = t.env->NewObject(j_cMyVector, j_mMyVector, x, y, j_sMessage);

        // now we can pass MyVector object to java side
        t.env->CallStaticVoidMethod(t.classID, t.methodID, j_oMyVector);

        // remember to remove objects we allocated
        t.env->DeleteLocalRef(j_sMessage);
        t.env->DeleteLocalRef(j_oMyVector);

        t.env->DeleteLocalRef(j_cMyVector);
        t.env->DeleteLocalRef(t.classID);
    }
}

}

and I attached full project file. You can check it.

1 Like

Hi Splash,
What if we move one step ahead…Now i want to pass this custom java object array to cocos2dx where i will manipulate it or you can say just use it for rendering purpose…?