[Kazehakase-devel 2527] Re: スクリプト言語による拡張をサポート

Zurück zum Archiv-Index

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です.



取り留めもなく書きましたが,ようは,風博士の言語バインディン
グを書くということです.



Kazehakase-devel メーリングリストの案内
Zurück zum Archiv-Index