将C ++对象返回给Java

时间:2011-06-07 18:59:54

标签: java c++ java-native-interface

我有几个JNI函数必须在同一个c ++对象上工作。我想将该对象保存在调用JNI函数的java对象中,但似乎Java无法存储稍后要访问的函数的指针。

好的,我意识到我在解释自己的工作非常糟糕,所以这里有一个例子:

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];
}

我的问题是创建一个jobject.myCppVector,以便我可以在不同的函数调用中使用它。

我希望有人理解我的谣言

1 个答案:

答案 0 :(得分:6)

我认为实现它的标准方法是在java中使用long来存储指针,这样你的java代码就可以在32位和64位系统上运行。显然,您需要为每个平台编译不同的C ++ .so / .dll。

因此,使用一个方法的C ++类的简单java包装器将类似于:

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 );
    }
}

你的C ++包装器代码看起来像这样。 (我已将C ++类命名为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
}