2012-10-02 54 views
1

我想通過一個NDK的C函數修改的Java SDK聲明全局變量,如訪問Java靜態字段:如何通過NDK

public class NDKTest extends Activity 
{ 
    static int myglobal = 0; 

    static { System.loadLibrary("MyCLib"); } 
    static public native void incrementmyglobal(); 
.... 

和MyCLib:

#include "NDKTest.h" 

JNIEXPORT void JNICALL Java_NDKTest_incrementmyglobal 

(JNIEnv * env, jobject jObj) 
{ 
    /* 
    this next line is obviously wrong, but illustrates how it would have 
    been done had it been a purely C program 
    */ 
    M.myglobal = M.myglobal + 1; 
    return; 
} 

所以我的問題是:

a /違規行的正確語法是什麼?

b/C頭文件應該如何查看?

c/Android.mk文件應該如何查看?

我可以編譯和運行各種'helloworld'NDK示例,但是我找不到任何可以說明如何修改在java中聲明的全局的 。一個超級簡單的例子將不勝感激!

我使用Linux命令行(ant調試)和簡單的文本編輯器(emacs)進行編程。我不使用Eclipse;已經編寫了C多年,並且是Java noob。 目標平臺是Android。 乾杯!

+0

據我記得,Java中的int!= int。對於Android NDK,他們被稱爲'jint'我相信。 – sschrass

+1

對於Android來說這不是一個特別的問題,它更多的是關於JNI的一般情況,偶爾嘗試谷歌的這個東西http://stackoverflow.com/questions/2630529/jni-how-to-access-java-object-integer – axis

+0

,該行: M.myglobal = M.myglobal + 1; 應該已經閱讀: NDKTest.myglobal = NDKTest.myglobal + 1; 沒有找到如何編輯我自己的問題 –

回答

0

該方法是靜態的,所以它的第二個參數是當前類的指針jclass,而不是當前的對象指針。另請注意,本機方法的名稱必須包括軟件包名稱:

JNIEXPORT void JNICALL Java_com_mypackage_NDKTest_incrementmyglobal 
(JNIEnv * env, jobject jcl) 
{ 
    jfieldID fid = GetStaticFieldID(env, jcl, "myglobal", "I"); 
    int i = GetStaticIntField(env, jcl, fid); 
    SetStaticIntField(env, jcl, fid, i+1); 
    return; 
} 

不需要C頭。 Android.mk應該看起來像任何helloworld示例,LOCAL_SRC_FILES已更改爲反映你的。

+0

我想這樣做的原因是爲了優化目的 - 我想要一個本地的c func來處理存儲在全局變量中的大量信息。你認爲我應該在C端存儲全局變量嗎? –

+0

它看起來像使用3行來操縱單個內存位置可能有點慢。否則,它是來自Seva的頂級答案 –

+0

對不起,這就是JNI的樣子。你不會得到更好的答案。你可以做的最好 - 你可以在某處緩存FieldID。在設計C/Java邊界時,請仔細考慮。 –