0

そこで、Android で実行する Palm Pilot プログラムを再作成しています。Cで書かれたライブラリを使い続けなければならないのですが、アプリのUIコンポーネントとBluetoothコンポーネントをAndroidで動くように書き直しています。Bluetooth 接続の相手側のデバイスを初期化するためにInitRelay、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_* 関数は、次の.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);

main methodのではold C program、InitRelay() は次のように呼び出されます。

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

渡されるパラメーターは、main メソッドで定義された関数です。これらの関数をすべて 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_* メンバーが関数ではないという理由で何千ものエラーが発生します。スクリーンショットは次のとおりです。

ここに画像の説明を入力

私もこの関数を追加して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;
}

上記の関数を書くように言われたチュートリアルはここにあります...

だから、私は何が間違っているのか分かりません。呼び出しは実際にはメソッド自体を返さないと思いGetMethodIDます....他に何をすべきか知っている人はいますか? 私はチュートリアルを読んでいて、それについて何かがありますCallVoidMethodが、私はそれを理解していません...ここにチュートリアルへのリンクがあります...

ご意見をお聞かせください。

4

1 に答える 1

1

メソッドなどの void メソッドのRelayAPI_flush場合。

JNI as に Java クラスがあり、呼び出してそのクラスのメソッドをjobject bluetoothClass取得した場合jmethodID

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

flushitJava次に、次のように Java関数を呼び出すことができます。

env->CallVoidMethod(bluetoothClass, RelayAPI_flush);

おそらく、VM との間でスレッドを正しくアタッチ/デタッチする必要があります。Android での JNI の使用に関するネット上のチュートリアルがあります。

http://java.sun.com/docs/books/jni/html/functions.htmlに従って JNI にある他のメソッドについては、

Call<Type>Method
<NativeType>
CallVoidMethod
void
CallObjectMethod
jobject
CallBooleanMethod
jboolean
CallByteMethod
jbyte
CallCharMethod
jchar
CallShortMethod
jshort
CallIntMethod
jint
CallLongMethod
jlong
CallFloatMethod
jfloat
CallDoubleMethod
jdouble
于 2012-07-26T14:14:37.423 に答える