2011-06-07 107 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 
}