2011-06-07 109 views
5

我得到了几个必须在同一个C++对象上工作的JNI函数。我想将该对象保存在通过其调用JNI函数的java对象中,但似乎Java没有办法将函数的指针存储为稍后访问的函数。将C++对象返回给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

也许指针转换为整数,然后整数存入Java对象 – ignis 2011-06-07 19:08:01

+0

的领域是不是被认为是不安全的?另外,在所有平台上,sizeof(jint)是否等于sizeof(void *)? – Afiefh 2011-06-07 19:22:12

+0

我不知道它应该是不安全的任何原因。但是,指针在不同的平台上有不同的大小,而Java的基本类型则不同,当然这意味着您需要将指针映射到Java代码中不同类型的基元 - int为32位,long为64位等。 http://java.sun.com/docs/books/jls/second_edition/html/typesValues.doc.html#85587 – ignis 2011-06-07 19:33:06

回答

4

我想到要去了解它的标准方法是使用长在java中存储的指针,这样,您的Java代码将在32位和64位系统上运行。显然你需要为每个平台编译一个不同的C++ .so/.dll。

所以一个简单的Java包装为一个C++类的一种方法看起来是这样的:

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 
}