2012-07-26 76 views
0

所以,我再造一個Palm Pilot掌上電腦程序在Android上運行。我必須繼續使用C編寫的庫,但我正在重寫應用程序的UI組件和藍牙組件以在Android中運行。要在藍牙連接的另一端初始化設備,我從C代碼中調用InitRelay的Android下使用NDK來,然後調用Java函數用C

這是原來的C代碼(尚未作出沒有變化):

fp_setbaud RelayAPI_SetBaud; 
fp_get RelayAPI_get; 
fp_put RelayAPI_put; 
fp_flush RelayAPI_flush; 
fp_delay RelayAPI_delay; 
fp_ProgressUpdate RelayAPI_ProgressUpdateTX; 
fp_ProgressUpdate RelayAPI_ProgressUpdateRX; 
... 

BYTE __stdcall InitRelay(fp_setbaud _setbaud, fp_get _get, fp_put _put, fp_flush _flush, fp_delay _delay){ 

    RelayAPI_SetBaud=_setbaud; 
    RelayAPI_get=_get; 
    RelayAPI_put=_put; 
    RelayAPI_flush=_flush; 
    RelayAPI_delay=_delay; 
    ... 
} 

的FP_ *函數typedef操作在.h文件是這樣的:

typedef void (__stdcall *fp_setbaud)(WORD); 
typedef short (__stdcall *fp_get)(WORD); 
typedef void (__stdcall *fp_put)(BYTE); 
typedef void (__stdcall *fp_flush)(void); 
typedef void (__stdcall *fp_delay)(WORD); 
//typedef void (__stdcall *fp_err)(WORD); 
typedef short (__stdcall *fp_ProgressUpdate)(WORD); 

old C programmain method ,InitRelay()被調用如下:

InitRelay(Changeit,getit,putit,flushit,delayit); 

傳遞的參數是主方法中定義的函數。我已經重寫了所有的在Java中的功能,並創建了一個新的C方法,它看起來是這樣的:

jmethodID RelayAPI_SetBaud; 
jmethodID RelayAPI_get; 
jmethodID RelayAPI_put; 
jmethodID RelayAPI_flush; 
jmethodID RelayAPI_delay; 
jmethodID RelayAPI_ProgressUpdateTX; 
jmethodID RelayAPI_ProgressUpdateRX; 
jclass bluetoothClass; 

BYTE __stdcall InitRelayJava(JNIEnv *env, jobject obj ) { 
    bluetoothClass = (*env)->GetObjectClass(env, obj); 

    RelayAPI_SetBaud=(*env)->GetMethodID(env, bluetoothClass, "changeitJava", "(I)Z" ); 
    RelayAPI_get =(*env)->GetMethodID(env, bluetoothClass, "getitJava" , "()V" ); 
    RelayAPI_put =(*env)->GetMethodID(env, bluetoothClass, "putitJava" , "([B)V"); 
    RelayAPI_flush =(*env)->GetMethodID(env, bluetoothClass, "flushitJava" , "()V" ); 
    RelayAPI_delay =(*env)->GetMethodID(env, bluetoothClass, "delayitJava" , "(I)V" ); 
    ... 
} 

當我嘗試編譯它,我得到成千上萬的錯誤所有我有多麼RelayAPI_的*成員AREN不起作用。下面是一個屏幕截圖:

enter image description here

我也被告知要添加這個功能來創建一個JVM,但我真的不理解的事....

JNIEnv* create_vm(JavaVM ** jvm) { 
    JNIEnv *env; 
    JavaVMInitArgs vm_args; 

    JavaVMOption options; 

    options.optionString = "-Djava.class.path=C:\\Users\\andrew\\workspace\\Singleton2\\src\\my\\eti\\commander"; 
    vm_args.version = JNI_VERSION_1_7; 
    vm_args.nOptions = 1; 
    vm_args.options = &options; 
    vm_args.ignoreUnrecognized = 0; 
    int ret = JNI_CreateJavaVM(jvm, (void**)&env, &vm_args); 
    if(ret < 0) 
     printf("\nUnable to Launch JVM\n"); 
    return env; 
} 

說叫我寫上面的功能是here教程...

所以,我不知道我做錯了。我假設GetMethodID呼叫實際上並不返回方法本身....有誰知道還能做什麼?我一直在閱讀教程,並有一些關於CallVoidMethod,但我不明白它...這裏是一個鏈接到tutorial ...

請讓我知道你的想法。

回答

1

對於無效的方法,如您RelayAPI_flush方法。

如果你在JNI爲jobject bluetoothClass您的Java類,並已通過調用

RelayAPI_flush = env->GetMethodID(bluetoothClass, "flushitJava" , "()V"); 

,那麼你可以調用Java flushitJava功能類似這樣的收購你的這個類的方法jmethodID

env->CallVoidMethod(bluetoothClass, RelayAPI_flush); 

你可能還必須安裝/拆卸線程/ VM從正確的有在Android中使用JNI關於在網絡上的教程。

對於我們還有其他方法JNI根據http://java.sun.com/docs/books/jni/html/functions.html

Call<Type>Method 
<NativeType> 
CallVoidMethod 
void 
CallObjectMethod 
jobject 
CallBooleanMethod 
jboolean 
CallByteMethod 
jbyte 
CallCharMethod 
jchar 
CallShortMethod 
jshort 
CallIntMethod 
jint 
CallLongMethod 
jlong 
CallFloatMethod 
jfloat 
CallDoubleMethod 
jdouble 
+0

什麼對於不是void的方法... – JuiCe 2012-07-26 14:16:11

+0

並且還,我將需要改變我的一些代碼,但讓我解釋一下,看看你能否提供幫助。RelayAPI_flush和其他人在整個圖書館的其他地方被稱爲數百次,我不想改變它們。所以我將創建方法ID,但必須設置'RelayAPI_flush = env-> CallVoidMethod(bluetoothClass,methodID)'。這是什麼類型?我知道它是無效的,但是我需要在我的代碼中多次使用它,並使用不同的函數,所以它必須是成員。 – JuiCe 2012-07-26 14:18:05

+0

哈哈添加別的東西,這可能看起來像一個愚蠢的問題,但我沒有C的經驗,我可以只聲明一些無效的東西嗎? – JuiCe 2012-07-26 14:18:47