ひわだです。

From: matz / netlab.co.jp (Yukihiro Matsumoto)
Subject: [ruby-ext:00822] Re: C++ の拡張ライブラリ
Date: Wed, 05 Jan 2000 03:45:49 +0900

> まつもと ゆきひろです

> |1. FILE* の typemap がほしい…

> 引数として IO をとるだけで良いのであれば、以下のようなのでい
> くんじゃないですかね。逆は結構つらそう。
> 
> %{
> #include "rubyio.h"
> %}
> 
> %typemap(ruby,in) FILE * {
>     OpenFile *fptr;
> 
>     Check_Type($source, T_FILE);    
>     GetOpenFile($source, fptr);
>     rb_io_check_writable(fptr);
>     $target = GetWriteFile(fptr);
> }

GetWriteFile で得た FILE* には書き込みしかできないのかと思ってました。
これで得た FILE* から読み込んでもいいんでしょうか。双方向パイプとかで
なければ問題ないのかな…。read 用と write 用両方いるのではと思ってまし
た。

例えばこんな感じに。

%{
typedef FILE FILE_for_read;
typedef FILE FILE_for_write;
%}

%typemap(ruby,in) FILE_for_read * {
  OpenFile *of;
  GetOpenFile($source, of);
  $target = GetReadFile(of);
}
%typemap(ruby,in) FILE_for_write * {
  OpenFile *of;
  GetOpenFile($source, of);
  rb_io_check_writable(fptr);
  $target = GetWriteFile(fptr);
}

void read_func(FILE_for_read *);
void write_func(FILE_for_write *);

From: Masaki Fukushima <fukusima / goto.info.waseda.ac.jp>
Subject: [ruby-ext:00823] Re: C++ の拡張ライブラリ
Date: Wed, 05 Jan 2000 13:59:02 +0900

> > |4. vector<T> とかのサンプルが欲しい
> 
> templateを用いて定義されたクラスをラップしたいということでしょう
> か? 今のSWIGではできないみたいです。

typedef しておけばなんとかなるので、

%{
typedef vector<string> vector_string;
%}
class vector_string {
public:
  void each() {
    for(vector<string>::iterator i = self->begin(); i != self->end(); ++i)
      rb_yield(rb_str_new(i->data(), i->size()));
  }
  void push_back(char *) { ... }
  ...
};

とか書いて Enumerable を include とかするとそこそこ使えるのですが、あ
らゆる vector についてすべて書くのは面倒なので。interface を継承するこ
とでなんとかならんかなあと考えていました。STL好きの戯言なので忘れちゃっ
てください。暇ができたらまた考えますけど。

> > 2. class を作ったときに %typemap(ruby,ignore), %typemap(ruby,argout) 
> >    をいちいち設定するのが面倒。いつも同じなのに…
> 
> ちょっとイメージがわかないんですが、
> これって具体的にどういう状況なんですかね。

たとえば、.i で

class Foo {};

とするだけで、ruby 側から Foo オブジェクトが見えるようになるわけですが、
例えば複数の値(Foo)を返す関数:

int func(Foo **OUTPUT, Foo **OUTPUT)

を使うために、僕は次のような typemap を書いています。

%typemap(ruby,ignore) Foo **OUTPUT(Foo *temp),
                      Bar **OUTPUT(Bar *temp)
{
  $target = &temp;
}
%typemap(ruby,argout) Foo **OUTPUT,
                      Bar **OUTPUT
{
  $target = output_helper($target, Wrap_$basetype(*$source));
}

class ならどれもいっしょのような気がする(確信はないが)ので、デフォル
トの typemap が設定できると楽だよなあと思いました。

--
檜田和浩 <hiwada / kuee.kyoto-u.ac.jp>