From: Masahiro S. ()
<sa...@to...> - 2006-06-14 06:56:11
|
酒井です。 From: "Kouhei Sutou" <ko...@co...> Date: Wed, 14 Jun 2006 11:11:48 +0900 > 須藤です. > > Ruby側で登録したコールバック(例えばsignal_connectとか)がCから呼び出される > とします.例えば,以下のようなプログラムで,以下のコマンドでコンパイルでき > ます. > > % cc `pkg-config gtk+-2.0 cairo --cflags --libs` \ > -I`ruby -rrbconfig -e 'print Config::CONFIG["archdir"]'` \ > -l`ruby -rrbconfig -e 'print Config::CONFIG["RUBY_SO_NAME"]'` \ > -o test test.c > > #include <gtk/gtk.h> > #include <ruby.h> > > int > main(int argc, char **argv) > { > gtk_init(&argc, &argv); > > ruby_init(); > ruby_init_loadpath(); > ruby_script(argv[0]); > ruby_set_argv(argc, argv); > > rb_eval_string("require 'gtk2'\n" > "Gtk.init\n" > "Gtk.timeout_add(0) do\n" > " raise 'timeout'\n" > "end\n"); > > gtk_main(); > > return 0; > } > > これを実行するとSegmentation faultで落ちます. > > (eval):3: [BUG] Segmentation fault > ruby 1.8.4 (2005-12-24) [i486-linux] このコードについては、Gtk.timeout_add で登録したブロックを呼び出す gtk_m_functionがrb_protectを使っていないのがまずいので、 それを修正すれば良いと思います。 > Rubyで書くとこんな感じですが,こちらは落ちません. > > require "gtk2" > > Gtk.init > Gtk.timeout_add(0) do > raise "timeout" > end > > Gtk.main こっちで落ちないのは、ruby_run()から実行されているため、 上のコードと異なり「例外でのジャンプ先」がちゃんとあるからです。 -- 酒井 政裕 / Masahiro Sakai |