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 ではエンコーディング指定の文字列を受け取るものがありますね。
処理系の内部エンコーディング => 指定のエンコーディング の変換とその逆(戻り値など)は

のどちらかでしょう。

良くあるパターンは後者でサポートし、歪なものは前者という選択肢を残すという感じでしょうか。