0

我正在为 Android 重新编写一个 Palm Pilot 程序,并且遇到了麻烦。我缺乏 C 经验让我完全无所适从。这是原始的 C 代码:

.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);

.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;
    RelayAPI_ProgressUpdateTX=0;
    RelayAPI_ProgressUpdateRX=0;
    ...
}

然后在代码的后面,这些函数调用如下:

if(baud9600) RelayAPI_SetBaud(9600);
else RelayAPI_SetBaud(1200);

old C文件的主要方法中InitRelay是这样调用的......

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

这五个参数都是在该主文件中声明的函数。

我想InitRelay从我的 Java 代码中调用,但它传递的所有这些函数都处理 Palm Pilot 功能。我已经为 Android 应用程序用 Java 重写了它们,并希望使用它们。所以,这就是我所做的......

jmethodID changeID;
jmethodID getID;
jmethodID putID;
jmethodID flushID;
jmethodID delayID;
// These two below are COMPLETELY wrong.
jmethodID RelayAPI_ProgressUpdateTX;
jmethodID RelayAPI_ProgressUpdateRX;
jclass    bluetoothClass;

BYTE __stdcall InitRelayJava( JNIEnv *env, jobject obj  ) {

bluetoothClass = (*env)->GetObjectClass( env, obj );

    changeID = (*env)->GetMethodID( env, bluetoothClass, "changeitJava", "(I)Z"  );
    getID    = (*env)->GetMethodID( env, bluetoothClass, "getitJava"   , "()V"   );
    putID    = (*env)->GetMethodID( env, bluetoothClass, "putitJava"   , "([B)V" );
    flushID  = (*env)->GetMethodID( env, bluetoothClass, "flushitJava" , "()V"   );
    delayID  = (*env)->GetMethodID( env, bluetoothClass, "delayitJava" , "(I)V"  );

    RelayAPI_SetBaud= env->CallBooleanMethod( bluetoothClass, changeID , int rate    );
    RelayAPI_get    = env->CallVoidMethod   ( bluetoothClass, getID                  );
    RelayAPI_put    = env->CallVoidMethod   ( bluetoothClass, putID    , byte[] buff );
    RelayAPI_flush  = env->CallVoidMethod   ( bluetoothClass, flushID                );
    RelayAPI_delay  = env->CallVoidMethod   ( bluetoothClass, delayID                );
    RelayAPI_ProgressUpdateTX=0;
    RelayAPI_ProgressUpdateRX=0;
    ....
}

我所做的有两个问题:1)在程序的 Android 版本中没有声明 RelayAPI_* 成员,因为我不知道命名它们的正确类型。2) 当我在 Android 版本中实际定义 RelayAPI_* 成员时,这根本不是我想要做的。这些env->CallXXXMethod调用实际上是在调用这些方法(我知道以一种不正确的方式,它写出来供您可视化)。我需要将这些成员设置为等于这些函数调用的 POINTERS。

如果有人知道我可以为这两个问题做些什么,请告诉我。如果我做错了,我也会很感激这些信息。这是我一直在使用的一些教程,但没有看到与我遇到的问题有关的任何内容。

教程 1

教程 2

教程 3

4

1 回答 1

1

像这样的东西怎么样:

typedef void (*fp_setbaud)(WORD);

void WrapSetBaud(WORD w) {
    env->CallBooleanMethod( bluetoothClass ...
}

fp_setbaud RelayAPI_SetBaud = WrapSetBaud;

等等。你得到我希望的照片。您必须将 env 全局保存在某个地方,以便包装器访问它。

于 2012-07-26T15:35:37.807 回答