2011-04-27 101 views
7

我試圖將結構作爲指針從JNI傳遞給Java,以便能夠稍後將它從Java傳回給JNI。我已閱讀此主題:Passing pointers between C and Java through JNI,但我沒有成功。將指針從JNI傳遞到Java使用long

我有一個相當複雜的結構:struct myStruct_s myStruct;

從Java,我稱之爲JNI函數初始化結構和長(指針結構)返回:

JNIEXPORT jlong JNICALL Java_example_ExampleJNI_getStruct(JNIEnv *jenv, jclass jcls) { 
    struct myStruct_s mystruct; 
    long *lp = (long*)&myStruct; 
    return lp; 
} 

然後我打電話一個具有那麼長參數的Java方法。在JNI中,我希望能夠使用之前創建的strcuture。我這樣做:

JNIEEXPORT jint JNICALL Java_example_ExampleJNI_methode1(JNIEnv *jenv, jclass jcls, jlong jarg) { 
    struct myStruct_s *arg = (struct myStruct_s *)&jarg; 
    ... 
} 

好吧,它不起作用。我猜想我長期投入結構是錯誤的。我應該怎麼做? 謝謝。


編輯:謝謝你的提示,這裏的工作職能

JNIEXPORT jint JNICALL Java_example_ExampleJNI_methode1(JNIEnv *jenv, jclass jcls, jlong jarg) { 
    struct myStruct_s *arg; 
    arg = (struct myStruct_s *)jarg; 
    ... 
} 

JNIEXPORT jlong JNICALL Java_example_ExampleJNI_getStruct(JNIEnv *jenv, jclass jcls) { 
    struct myStruct_s *myStruct; 
    myStruct = (struct myStruct_s *)malloc(sizeof(struct myStruct_s)); 
    long lp = (long)myStruct; 
    return lp; 
} 
+1

請注意,根據目標平臺,「jlong​​」不一定等於「long」。如果你在一個實際上是「長久」的平臺上運行它,這將會失敗,所以你應該總是明確地使用「jlong​​」。 – NeoNacho 2013-04-25 13:50:51

+0

leochab,但你將如何訪問在Java層的strct對象。如何訪問struct中定義的局部變量。也有可能做一些C++類對象。我跟隨類似[這裏](http://stackoverflow.com/q/32840427/2624806)。 – CoDe 2015-09-29 09:46:08

回答

5

在您的例子

struct myStruct_s mystruct; 

是在棧中的局部變量,因此無法使用函數返回後。 Possubly這只是你的代碼的一個縮減,但如果不是,那麼使用malloc(sizeof(struct myStruct_s))來獲得堆分配。

然後提出了你什麼時候釋放該分配的問題,注意內存泄漏。

1

在additiona到@莫伊茲的建議,我將指針轉換爲long ratehr比long *

long lp = (long)&myStruct; 
3

這種結構的記憶被破壞,返回後的方法,因爲它被放入堆棧,而不是到堆中,試試吧:

JNIEXPORT jlong JNICALL Java_example_ExampleJNI_getStruct(JNIEnv *jenv, jclass jcls) { 
    long *lp = (long*)malloc(sizeof(struct myStruct_s)); 
    return lp; 
} 

PS:爲什麼 *,而不是簡單的