2012-07-06 84 views
0

我正在創建一個Android應用程序,它從C庫中提取方法。一個C庫中所使用的方法看起來像這樣...(按照指針val這是作爲功能second parameter通過。)使用NDK時指針/參考

BYTE __stdcall GetVal(WORD what, long *val){ 
DWORD relaydate; 
BYTE tmpb; 
DWORD tmpd; 
WORD tmp; 
#ifdef HASTHAILANDSWAP 
WORD what2; 
#endif 

if(val) *val=0; 
if(!CheckInit()) return ERR_NOT_INIT; 
if(what==VAL_NULL){ 
    if(RelayAPI_DataValid){ 
     return 0; 
    }else{ 
     return -1; 
    } 
} 
if(!CheckValid()) return ERR_READ_FAIL; 

switch(what){ 
    case VAL_SWVERSION: 
     *val=RelayAPI_SWVersion; 
     return 0; 
    case VAL_VOLTAGE: 
     *val=RelayAPI_Voltage; 
     return 0; 
    case VAL_VERSION: 
     *val=RelayAPI_Version; 
     return 0; 
    case VAL_ISSMUD: 
     *val=RelayAPI_isSMUD; 
     return 0; 
} 

甲​​被定義爲unsigned char。我需要從我的Java函數中調用GetVal方法。我的Java代碼應與此C代碼的功能...

long val; 
char buff[20]; 
if(!GetVal (VAL_SERIAL, &val)) {} 

而且這是我迄今爲止在我的Java代碼(我知道這是不對的,我知道你不能使用引用在Java中那樣的,我只是顯示你我有什麼):

public void updateForm() { 
    int val; 
    char buff[]; 

    /** 
    * SERIAL NUMBER 
    */ 
    if(!GetVal(RelayAPIModel.VAL_SERIAL, &val)) { } 
} 

所以,val被初始化爲null(我假設,我不知道的C太清楚),參考這一長期通過函數傳遞。在該函數內,指向val的指針被分配一個值。

有沒有辦法在C中使用一個方法,該方法傳遞一個對NULL變量的引用,然後將該變量賦值給一個值?

編輯:

爲了澄清,我使用含有上述GETVAL方法的庫。我正在鏡像Palm Pilot API,這是第二個代碼塊的來源。第三個代碼塊是我從Java調用到C庫中的GetVal方法。

+0

您可以發佈JNI封裝的功能? – Renard 2012-07-06 14:11:12

+0

我很樂意,但你是什麼意思的包裝功能? – JuiCe 2012-07-06 14:12:27

+0

我假設你使用jni從java調用native c?如果是這樣,請發佈您的jni代碼。 – Renard 2012-07-06 14:15:58

回答

0

如果我正確理解你,你想讓GetVal方法改變傳入的參數。由於java沒有指針,你需要創建一個簡單的java類,你可以在你的c代碼中進行操作。

因爲我不知道你的jni代碼,我不得不做很多猜測,所以不要採取源代碼。 但它應該讓你走上正軌。

Java代碼

class LongWrapper { 
    private long mValue; 
    public void setValue(final long value){ 
     mValue = value; 
    } 
} 

native boolean GetVal(int valSerial,LongWrapper val); 

的JNI代碼示例

jboolean Java_com_foo_GetVal(JNIEnv *env, jint val_serial, jobject longObj) 
{ 
    jclass cls = env->GetObjectClass(longObj); 
    jmethodID mid = env->GetMethodID(cls, "setValue", "(J)V"); 
    if (mid == 0) { 
     return false; 
    } 
    jlong val=0; 
    bool result = GetVal(val_serial,&val) 
    env->CallLongMethod(longObj,mid, val); 
    return result 
} 
+0

謝謝,那正是我期待的。但是,我試圖在不更改C代碼的情況下將其關閉。這甚至有可能嗎? – JuiCe 2012-07-06 14:47:09

+0

具有公共數據字段的Java類將執行此操作。這種方式減少了JNI管道。 – 2012-07-06 14:47:09

+0

@JuiCe:Java不支持原始引用,也不支持輸出參數。所以不行。 – 2012-07-06 14:49:07