From: Paul Brannan Date: 2008-01-09T06:35:59+09:00 Subject: Re: Embedding 1.9 On Wed, Jan 09, 2008 at 02:04:03AM +0900, Dave Thomas wrote: > int main(int argc, char **argv) { > VALUE result; > > ruby_sysinit(&argc, &argv); > RUBY_INIT_STACK; > ruby_init(); > ruby_init_loadpath(); > > rb_require("sum.rb"); > rb_eval_string("$summer = Summer.new"); > rb_eval_string("$result = $summer.sum(10)"); > result = rb_gv_get("result"); > printf("Result = %d\n", NUM2INT(result)); > ruby_finalize(); > exit(0); > } Before I added sum.rb: class Summer def sum(*args) args.inject { |sum, x| sum + x } end end I was getting a segfault running your example: [pbrannan@zaphod embed]$ ./embed :17: [BUG] Segmentation fault ruby 1.9.0 (2008-01-04 revision 0) [i686-linux] Your example should catch exceptions: VALUE embeded(VALUE ignore) { VALUE result; rb_require("sum.rb"); rb_eval_string("$summer = Summer.new"); rb_eval_string("$result = $summer.sum(10)"); result = rb_gv_get("result"); printf("Result = %d\n", NUM2INT(result)); return Qnil; } int main(int argc, char **argv) { int state; ruby_sysinit(&argc, &argv); RUBY_INIT_STACK; ruby_init(); ruby_options(argc, argv); rb_protect(embeded, Qnil, &state); return ruby_cleanup(state); } to prevent the segfault: [pbrannan@zaphod embed]$ mv sum.rb sum_bk.rb [pbrannan@zaphod embed]$ ./embed ruby 1.9.0 (2008-01-08 revision 0) [i686-linux] :17: no such file to load -- sum.rb (LoadError) I also removed the call to exit(0) and replaced ruby_init_loadpath() with ruby_options(). I think there's still some work left to do, because: - the filename is wrong ("dummy toplevel"). - TOPLEVEL_BINDING is undefined - NameError exceptions aren't getting caught (the program just exits) - I can't require shared objects (rb_require("socket") gives an error about rb_eRuntimeError being undefined) I don't know which of these are bugs in my code and which are bugs in the interpreter. BTW, how are you determining which options to pass to the compiler/linker? I feel there should be a better way than what I'm doing: ruby_config() { ruby1.9 -rrbconfig -e "puts Config::CONFIG['$1']" | grep -v "ruby 1.9.0"; } gcc embed.c -o embed \ -I `ruby_config rubyhdrdir` \ -I `ruby_config rubyhdrdir`/`ruby_config arch` \ -L `ruby_config libdir` \ `ruby_config LDFLAGS` \ `ruby_config LIBS` \ `ruby_config LIBRUBYARG` I'm unsure whether I should be using LDFLAGS above, since it contains the string "-L.", which seems wrong. Paul