mRubyとC++の親和性

オートパイロットシステムTinyFeathermRubyを載せて遊んでいます。最近はextend_sample.rbに示したようなRubyのコードで誘導制御の部分も動くようになりました。これはmRubyから既存のコードを呼び出すことで可能となったのですが、既存のコードの大半はC++で書いてあります。せっかくなので、mrubyをC++のオブジェクト指向を意識して融合することにしました。

mRubyはC言語で書いてあります。そういった事情からC++のオブジェクト指向的な方法でコードを融合するのは難しいのでは、もしかしたらmRuby自体の書き換えが必要かも、と思っていたのですが、そんなことはありませんでした。
結論から言ってしまうと、mrb_state構造体にあるvoid型ポインタ変数udが自由に使えるようになっており、この変数に必要なインスタンスへのポインタを格納すれば、mRubyの1インスタンスあたり、1つのオブジェクトを関連付けることができます。

mrb_state構造体の定義はmruby.hにあり、そこには/* auxiliary data */のコメントがあります。補助データ、ということでとても匂います。
さらに実際にこのudを自由に使っていいものか検証してみます。state.cの33行目付近を見ると、mrb_open_allocf()から呼び出されるメモリアロケータmrb_allocfに渡された引数の1つがudとして格納されています。それ以降、変数udの値を変更はしていないようです。またカスタムアロケータを使わず、通常のmrb_open()を使ってmrb_stateを初期化している場合、mrb_open_allocf()内で変数udにはNULLが指定されます(state.cの94行目)。ということで通常の手順であれば、mrb_open()の後に一度udにNULLが代入された後は、udは自由に使っても問題がないことがわかりました。

TinyFeatherではこれらのテクニックをshell.cppのかなり後の部分(930行目付近)で使っています。なおshell.cppはmRubyと既存のコードの糊として働いている部分です。

June 01, 2013 23:59 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク

コメント

コメントする