C++メンバ関数をコールバック関数とする場合の妄想的改善案

STATUS: 故障中

 C++のクラスのメンバ関数をコールバック関数とする場合、そのメンバ関数をstatic関数にして、コールバック時にthisポインタを渡してもらいます。

【参考URL】
コールバック関数をクラスのメンバとするには?
MFC でコールバック関数を使う

 さて、lua言語を組み込んで独自機能を追加する場合、関数ポインタを設定してコールバック的に呼び出してもらうわけですが、この場合もthisポインタを返してもらう必要があります。
 でもluaスクリプト内で、thisポインタを扱わせるのは危なっかしいです。値を間違ったり省略したら即落ちますし、スクリプト中でいちいちthisポインタ渡すのがめんどくさい。
 コールバック関数内で、thisポインタの有効性をチェックしたり、ポインタの変わりにIDか何かを使ってもいいのですが、パフォーマンスが心配です。

● 改善案

 thisポインタをセットしてからコールバック関数を呼び出す(マシン語)コードを生成して、そのコードへのポインタをコールバック関数として設定すれば、よいのではないかと考えました。
 以下の、CallbackHelperクラスでは、上記の処理を実装したものです(ただし、C++もどきなテケトーコードです)。
 使用例では、lua_register関数の第3引数として、メンバ関数MyFuncをコールバック関数として登録しています。
 コールバック関数が呼ばれる際は、thisポインタもちゃんと渡されるため、static関数にする必要はありません。便利〜。
 登録するコールバック関数の数だけCallbackHelperのインスタンスが必要になりますが、1個10byteそこらなので問題ないでしょう。

【コールバックヘルパクラス】(概念的なソース)

class CallbackHelper {
        BYTE byteCode[10];
        void* Create( void *pThis , void* pfCallback ) {
                // コールバック関数にthisポインタを渡すコードを生成する

                // thisポインタを設定(ecxレジスタと仮定 コンパイラ依存)
                byteCode[0] = 0xb9; // mov ecx,pThis
                byteCode[1 .. 4] = pThis;

                // 本来のコールバック関数へジャンプ
                byteCode[5] = 0x0f; // jp pfCallback
                byteCode[6 .. 9] = pfCallback;

                return byteCode;
        }
};

【使用例】

class MyClass {
        CallbackHelper ch;
        lua_Statech *m_pLua;

        MyClass() {
                m_pLua = lua_open();
                lua_baselibopen(m_pLua);
                lua_register( m_pLua, "MyFunc",ch.Create(this,MyFunc) ); // ココでコールバック関数を登録
                // 以下略
        }

        int MyFunc( lua_State *L ); // コールバック関数
};

● 改善案の問題点

・データ領域でコードを実行するので、WinXPの新しいSPでは動かないかも
・ヘルパクラスで生成するコードがコンパイラ依存
・そもそもこれ動くのか?
luaの場合は、適当な(luaスクリプト内の)グローバル変数にでもthisポインタを突っ込んでおいてコールバック関数(static)内で勝手取得して使えば良いということに気づいてしまった…
lua_State自体にthisポインタを指定できたら便利だな(実は出来たりして)

コメント

サアラ montana 'Rubens'

STATUS: 故障中

 アゾン秋葉原レーベルショップで新しいサアラたん(montana 'Rubens')を入手できました。
 店頭に無かったので売り切れかとあせりました(18:00頃だったので)が、店員に聞いたら奥から出してきてもらえました。(たまたま店頭のものが売り切れてしまっていたらしい)
 なんか店の中の配置が変わっていて、一部袋小路になってました。意図不明。
 ドールショーで出ていた60cm Mayaもいました。1/6より可愛くなってます。が、さすがに買えませんよ。

 『SAHRA』montana 'Rubens'
 写真その1
 写真その2

 まだ箱入りです。衣装はちょっとサアラたんのイメージに合わないかも〜と思います。

コメント

m.i.a. cafe

STATUS: 故障中

 コールバックを実装しようにもdelegateがデリケートなので、ミアカフェに行ってきました。
 キュアメイドカフェより普通の喫茶店という感じ。店員さんもメイド服着てるけど普通に店員かなというのが入ってからの第一印象。
 が、実は結構感じがいいです。メイドさんといろいろお話できるのがイイ。飲み物のおかわり頼むと割引券のくじ引きをするゲームみたいのがあって楽しい。つい3回もおかわりしてしまって、今日は甘いもの飲み過ぎ。
 あんまりシステマティックになってないのがいいですね。特に時間制限とかないようなので、本とか読んでのんびりしてきました。
 お客さんを見ていると常連率が高いみたいです。客同士知り合いということがよくありました。ちょっと戸惑う。なんか、orkutgreeで見たことある人が居たような気がしたけど、これは自信なし。ノートパソコン開いている人が何人かいて秋葉だな〜と。
 今日は新人のみるくさん(ベタな名前だ…)が、とても頑張っててかわいかった。話し方が丁寧なのがよいです。ヲレゲな例えだとギャラクシーエンジェルWindows版ゲーム版のミントさんみたいな感じか。ちょっと語尾がセリフぽく不自然なところがイイ(ぉ

コメント