[ruby-ext:02325] C++のフックメソッドをRubyで書くには?

View: New views
5 Messages — Rating Filter:   Alert me  

[ruby-ext:02325] C++のフックメソッドをRubyで書くには?

by Ichitaro Masuda :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

はじめまして。増田です。
初歩的なことで恐縮なのですが、C++の拡張ライブラリの書き方で質問です。

updateというコールバック用のメソッドを持つ、以下のような既存のC++ライブラリのクラスがあり、

class ofSimpleApp {
       public:
               virtual void update(){}
};

このコールバックをRubyで書けるようにすべく、対応するRubyオブジェクトを作ってサブクラスで定義したいと思っております。

# Ruby側からは以下のような感じで使えるようにしたい
AppRunner.runApp(Class.new(SimpleApp) do
 def update
   # 描画ループ
 end
end.new)

私なりにやってみたものが、以下になります。
あまり作法が分からず、RubyでラップするC++クラスに、自身のRubyラッパの参照を持たせてしまいました。
updateが呼び出されると、対応するRubyラッパのメソッドを呼び出します。

static int id_update = rb_intern("update");

class mySimpleApp : public ofSimpleApp {
       public:
               void update();
               VALUE ruby_obj;
};

void mySimpleApp::update() {
       rb_funcall(ruby_obj, id_update, 0);
}

肝心の拡張ライブラリのメインの部分ですが、以下のようにしています。

static VALUE cMySimpleApp;

//きっとマーク関数が必要だろうと推測
void mark_sa(mySimpleApp *app)
{
       rb_gc_mark(app->ruby_obj);
}

VALUE alloc_sa(VALUE klass)
{
       return Data_Wrap_Struct(klass, mark_sa, 0, new mySimpleApp);
}

VALUE initialize_sa(VALUE self)
{
       mySimpleApp *app;
       Data_Get_Struct(self, mySimpleApp, app);
       app->ruby_obj = self;
       return self;
}

#ifdef __cplusplus
extern "C" {
#endif
void Init_rbof(void)
{
       cMySimpleApp = rb_define_class("SimpleApp", rb_cObject);
       rb_define_alloc_func(cMySimpleApp, alloc_sa);
       rb_define_method(cMySimpleApp, "initialize", (RubyType
*)initialize_sa, 0);
}
#ifdef __cplusplus
}
#endif

これで動いてはいるものの、GC的に何かやってはならないことを犯しているのではと不安です。「C++のフックメソッドに対応するRubyのフックメソッド」は通常どのように実装されるのでしょうか・・?

C++もRubyの拡張ライブラリも初めてでして、かなりおかしなことをしているかもしれませんが、もし何か参考になるソースなどありましたら、ご教授いただけると幸いです。よろしくお願い致します。


[ruby-ext:02326] Re: C++のフックメソッドをRubyで書くには?

by Yukihiro Matsumoto :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

まつもと ゆきひろです

In message "Re: [ruby-ext:02325] C++のフックメソッドをRubyで書くには?"
    on Mon, 2 Jun 2008 13:34:47 +0900, "Ichitaro Masuda" <ichitaro.masuda@...> writes:

|初歩的なことで恐縮なのですが、C++の拡張ライブラリの書き方で質問です。

|これで動いてはいるものの、GC的に何かやってはならないことを犯しているのではと不安です。「C++のフックメソッドに対応するRubyのフックメソッド」は通常どのように実装されるのでしょうか・・?

ソースを呼んでみて気になる点は

  * newでC++オブジェクトを割り当てているがdeleteしているよう
    に見えない
  * ruby_objメンバが初期化されないことがありえる

でした。どちらも些細なことですが。他はおおむね大丈夫なんじゃ
ないかと思いました。ま、ひとめ見ただけではわからないバグと言
うのは珍しくはないのですが。


[ruby-ext:02327] Re: C++のフックメソッドをRubyで書くには?

by Ichitaro Masuda :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

増田です。

早速のご指摘ありがとうございます。感謝致します。

> ソースを呼んでみて気になる点は
>
>  * newでC++オブジェクトを割り当てているがdeleteしているよう
>    に見えない
>  * ruby_objメンバが初期化されないことがありえる

勉強になります。では、以下のように変更すれば大丈夫でしょうか?

void free_sa(mySimpleApp *app)
{
       delete app;
}

VALUE alloc_sa(VALUE klass)
{
     mySimpleApp *app;
     VALUE obj;

     app = new mySimpleApp();
     obj = Data_Wrap_Struct(klass, mark_sa, free_sa, app);
     app->ruby_obj = obj;
     return obj;
}

2008/06/02 14:13 Yukihiro Matsumoto <matz@...>:

> まつもと ゆきひろです
>
> In message "Re: [ruby-ext:02325] C++のフックメソッドをRubyで書くには?"
>    on Mon, 2 Jun 2008 13:34:47 +0900, "Ichitaro Masuda" <ichitaro.masuda@...> writes:
>
> |初歩的なことで恐縮なのですが、C++の拡張ライブラリの書き方で質問です。
>
> |これで動いてはいるものの、GC的に何かやってはならないことを犯しているのではと不安です。「C++のフックメソッドに対応するRubyのフックメソッド」は通常どのように実装されるのでしょうか・・?
>
> ソースを呼んでみて気になる点は
>
>  * newでC++オブジェクトを割り当てているがdeleteしているよう
>    に見えない
>  * ruby_objメンバが初期化されないことがありえる
>
> でした。どちらも些細なことですが。他はおおむね大丈夫なんじゃ
> ないかと思いました。ま、ひとめ見ただけではわからないバグと言
> うのは珍しくはないのですが。
>
>


[ruby-ext:02328] Re: C++のフックメソッドをRubyで書くには?

by Yukihiro Matsumoto :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

まつもと ゆきひろです

In message "Re: [ruby-ext:02327] Re: C++のフックメソッドをRubyで書くには?"
    on Mon, 2 Jun 2008 14:50:51 +0900, "Ichitaro Masuda" <ichitaro.masuda@...> writes:

|>  * newでC++オブジェクトを割り当てているがdeleteしているよう
|>    に見えない
|>  * ruby_objメンバが初期化されないことがありえる
|
|勉強になります。では、以下のように変更すれば大丈夫でしょうか?

たぶん大丈夫だと思います。


[ruby-ext:02329] Re: C++のフックメソッドをRubyで書くには?

by Ichitaro Masuda :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

増田です。

お忙しいところ応じていただき、どうもありがとうございました。
悪さをしないライブラリが書けるよう精進したいと思います。

2008/06/02 15:07 Yukihiro Matsumoto <matz@...>:

> まつもと ゆきひろです
>
> In message "Re: [ruby-ext:02327] Re: C++のフックメソッドをRubyで書くには?"
>    on Mon, 2 Jun 2008 14:50:51 +0900, "Ichitaro Masuda" <ichitaro.masuda@...> writes:
>
> |>  * newでC++オブジェクトを割り当てているがdeleteしているよう
> |>    に見えない
> |>  * ruby_objメンバが初期化されないことがありえる
> |
> |勉強になります。では、以下のように変更すれば大丈夫でしょうか?
>
> たぶん大丈夫だと思います。
>
>