Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return C++ object to Java

I got a couple of JNI functions that have to work on the same c++ object. I would like to save that object in the java object through which the JNI functions are invoked, but it seems that Java has no way to store pointers for functions to access later.

Okay I realize that I'm doing a terrible job explaining myself so here is an example:

void clear_numbers(JNIEnv *env, jobject me) {
   me.myCppVector.clear();
}

void set_number(JNIEnv *env, jobject me, jint index, jint num) {
   me.myCppVector[index]=num;
}

jint get_number(JNIEnv *env, jobject me, jint index) {
   returnme.myCppVector[index];
}

My problem is creating a jobject.myCppVector so that I'll be able to use it from different function calls.

I hope someone understands my ramblings

like image 406
Afiefh Avatar asked Jun 07 '11 18:06

Afiefh


1 Answers

I think the standard way of going about it is to use a long in java to store the pointer, that way your java code will work on both 32bit and 64bit systems. Obviously you need to compile a different C++ .so/.dll for each platform.

So a simple java wrapper for a C++ class with one method will look something like:

class JavaClass
{
    private long native_ptr = 0;
    private native long createNativeInstance( params );
    private native String nativeMethod( params );
    private native void destroyNativeInstance( long p_native_ptr );
    public JavaClass( params )
    {
        this.native_ptr = createNativeInstance( params );
    }
    public String javaMethod( params )
    {
        nativeMethod( this.native_ptr, params );
    }
    public void finalize()
    {
        destroyNativeInstance( this.native_ptr );
    }
}

And your C++ wrapper code looks something like this. (I have named the C++ class CppClass)

JNIEXPORT jlong JNICALL Java_JavaClass_createNativeInstance
    ( JNIEnv*   p_jenv
    , jobject   p_jthis
    , params )
{
    // Convert params from Java types to C++ types if required
    return (jlong) new CppClass( converted_params );
}

JNIEXPORT void JNICALL Java_JavaClass_destroyNativeInstance
    ( JNIEnv*   p_jenv
    , jobject   p_jthis
    , jlong     p_native_ptr )
{
    if( p_native_ptr )
        delete (CppClass*)p_native_ptr;
}

JNIEXPORT jstring JNICALL Java_JavaClass_nativeMethod
    ( JNIEnv*   p_jenv
    , jobject   p_jthis
    , jlong     p_native_ptr
    , params
    )
{
    // Convert params from Java types to C++ types if required
    std::string cpp_result = ((CppClass*)p_native_ptr)->cppMethod( converted_params );
    jstring java_result = p_jenv->NewStringUTF( cppResult.c_str() );
    return java_result;
    // NOTE: std::string destructor will free cpp_result memory
}
like image 88
Sodved Avatar answered Oct 21 '22 17:10

Sodved