Foreign Function Interface その2
同じく M さんに以下の点で理解や調べが足りないとご指摘を受けました。
- callback のある関数はどうするのか?
- C の qsort 関数のようなものを呼ぶときは?
- mbcsを受けとる関数を呼ぶ時に変換するのは誰の仕事か?またその寿命管理は?
確かに甘かったので調べます。ありがたいご指摘です。
callback のある関数はどうするのか?
例えば非同期処理で一度結果が返され、その後 callback される場合はどうしたら良いだろうか?
すぐに思いつくのは JNI でいうところの env を利用して callback 関数から Java のコードを呼ぶこと。
この場合 callback される関数も自分でCで書かないといけない。
void do_something_callback() { env->javaを呼ぶ } void hoge(env) { do_something(do_something_callback); }
さらに VM に非同期に割り込むので VM が callback を考慮していないと死んでしまいそう。
と思って調べてみました。
JNIEXPORT void JNICALL Java_DirectoryWatcher_watchDirectory(JNIEnv *env, jobject obj) { env->GetJavaVM( &m_vm ); Watcher * w=new Watcher(); w->Go("c:\\test"); return; } void doCallback(){ m_vm->AttachCurrentThread( (void**) &m_env, NULL ); jclass cls = m_env->FindClass( "DirectoryWatcher" ); jmethodID mid = m_env->GetMethodID(cls, "callback", "(I)V"); m_env->CallStaticVoidMethod(cls, mid); }
なるほど AttachCurrentThread でスレッドを attach するのか。納得。
C の qsort 関数のようなものを呼ぶときは?
qsort の compare 関数をどう渡すか?
他の引数は C の世界の型に変換されているはずだから2通りかな。
- Cで compare を書く
- ターゲットに特有の DSL ?か何かで compare を書く。
mbcsを受けとる関数を呼ぶ時に変換するのは誰の仕事か?またその寿命管理は?
まずは mbcs が分かりません。MBCSとは 【Multiple Byte Character Set】 - 意味・解説 : IT用語辞典だそうです。
確かに C の API ではエンコーディング指定の文字列を受け取るものがありますね。
処理系の内部エンコーディング => 指定のエンコーディング の変換とその逆(戻り値など)は
のどちらかでしょう。
良くあるパターンは後者でサポートし、歪なものは前者という選択肢を残すという感じでしょうか。