Kouhei Sutou
kou****@cozmi*****
2006年 1月 7日 (土) 21:47:59 JST
須藤です. # なんかぐだぐだ書いちゃいました... In <20060****@on-ai*****> "[Kazehakase-devel 2522] Re: スクリプト言語による拡張をサポート" on Thu, 5 Jan 2006 18:50:42 +0900, Ryo SHIMIZU <furyo****@on-ai*****> wrote: > > 一応,手元には(というか後輩に書いてもらった)Rubyで拡張する > > ためのコードがありますが,ちょっと訳あってまだコミットしてい > > ません.他の言語で拡張したいという人がいたら相談にのるので聞 > > いてください. > > 僕は Perl しか書けない(書けてるつもりの)人間なので,Perl も > あったりすると嬉しいです. 私はRubyしか書けませんが. X) > ただ, > > > 3.3 風博士とスクリプト言語をつなぐ部分をCで書く > > というのがどういう事なのか理解できていないため,Perl を > サポートしようとするとどのぐらい大変なのか分かりません. えーと,まず,以下のように風博士の世界とPerlの世界があります よね. +-------------------+------------------+ | 風博士の世界 | Perlの世界 | +-------------------+------------------+ で,Perlから風博士のオブジェクト(KzWindow)とかをいじれない のはわかりますよね?なぜなら,風博士の世界はCで,Perlの世界 はPerlですから. ですが,これらの世界の間に越えられない壁があるわけではなくて, 以下のようにこれらの世界を繋げられる領域があります. +-------------------+------------------+ | 風博士の世界 | Perlの世界 | +-------------------+------------------+ <---------- C ----------><- Pure Perl -> ===== ここ これが「風博士とスクリプト言語をつなぐ部分をCで書く」部分で す. Perlの世界にCがあるのは,PerlがCで実装されていて,さらに, PerlがCのAPIを公開しているからです. # よくわかりませんが,たぶん,「Perlの世界での"func"という名 # 前をCのc_funcという関数に対応づける」とかいうのがあると思 # います. 例えば, GtkWidget *kz_window_open_new_tab (KzWindow *kz, const gchar *url); をPerlの世界から呼び出したいとします. そのためには,まず,「風博士の世界でのCの型」を「Perlの世界 でのCの型」に変換しなければいけません.これが↑の図の「ここ」 の部分でやる大事なことのひとつです. もう少しいうと,「ここ」では (1) 「風博士の世界でのCの型」を「Perlの世界でのCの型」に変 換するラッパー関数をCで書く (2) ラッパー関数がPerlの世界で見えるようにPerlのCのAPIを使っ てラッパー関数を登録する ということをします. 私はPerlの世界のCを知らないので,以下,適当に書きます.と思っ たのですが,全然わからないのでRubyの世界のCで書きます. まず,(1)では例えば以下のような関数を書きます. static VALUE wrap_kz_window_open_new_tab(VALUE self, VALUE url) { GtkWidget *embed; embed = kz_window_open_new_tab(KZ_WINDOW(RVAL2GOBJE(self)), RVAL2CSTR(url)); return GOBJ2RVAL(embed); } VALUEがRubyの世界のCの型です.このラッパー関数では * 引数として渡されたRubyの世界のオブジェクトを風博士の世界 のオブジェクトに変換 * VALUE selfをKzWindow *に変換(KZ_WINDOW(RVAL2GOBJE(self))) * VALUE urlをchar *に変換(RVAL2CSTR(url)) * 戻り値の風博士の世界のオブジェクトをRubyの世界のオブジェ クトに変換 * GtkWidget *embedをVALUEに変換(GOBJ2RVAL(embed)) ということをしています. (2)はRubyでは以下のようにします. rb_define_method(cKzWindow, "open_new_tab", wrap_kz_window_open_new_tab, 1); rb_define_methodはRubyが公開している「cKzWindowクラスに open_new_tabという1引数で,処理本体は wrap_kz_window_open_new_tabであるメソッドを定義する」というC のAPIです. 取り留めもなく書きましたが,ようは,風博士の言語バインディン グを書くということです.