Questions about embedding Ruby in C

I have some questions regarding how to embed Ruby into C apps:

  1. How can I make Ruby not calling exit() when finished with a script?
    I’ve already seen the variant using rb_set_end_proc(), but is there
    any other way to do it since the program still dies after calling the
    rb_set_end_proc()?

  2. How does it come I can’t see any output from the script I’m
    running? Is it because Ruby decides to run it in a sub-shell or what?

  3. Is it possible to make the interpreter use rubyated C-code from the
    application who called it like an extension library? And if so, how?

Thanks.

-Johan

1. How can I make Ruby not calling exit() when finished with a script?

Just don't call ruby_run()

2. How does it come I can't see any output from the script I'm
running? Is it because Ruby decides to run it in a sub-shell or what?

Well, you must give an example to see what you are trying to do.

3. Is it possible to make the interpreter use rubyated C-code from the
application who called it like an extension library? And if so, how?

Look in RAA you have many examples

Guy Decoux

Or at least, is there any documentation aviable on the subject?

ts decoux@moulon.inra.fr wrote in message news:200211210931.gAL9V5A16309@moulon.inra.fr

  1. How can I make Ruby not calling exit() when finished with a script?

Just don’t call ruby_run()

  1. How does it come I can’t see any output from the script I’m
    running? Is it because Ruby decides to run it in a sub-shell or what?

Well, you must give an example to see what you are trying to do.

  1. Is it possible to make the interpreter use rubyated C-code from the
    application who called it like an extension library? And if so, how?

Look in RAA you have many examples

Guy Decoux

?

  1. But if I don’t call ruby_run(), how does it interpret?

  2. When I am running a script, say with the line
    puts ‘hello’
    from within my c-program, no ‘hello’ pops up on my term.

  3. What I meaned was like:

    c program:
    VALUE ruby_func()
    {
    /* … */
    }

     void blah_blah()
     {
         ruby_init();
         ruby_script("foo.rb");
         ruby_run();
     }
    

    foo.rb:
    # …
    ruby_func # call ruby_func that appeared in the
    # … # same app as the caller of ruby_run()

    Is this kind of operation possible?

-Johan

Johan Persson wrote:

Or at least, is there any documentation aviable on the subject?

Hi Johan!

I looked through a bunch of examples in the RAA, and here

is what I hacked together, and it seems to work… I’m just a newbie,
so take it all with a grain of salt…
– Glenn

···

=======================================================================

#include <ruby.h>
#include <stdio.h>

static VALUE defout_write(VALUE self, VALUE str)
{
str = rb_obj_as_string(str);
fprintf(stderr, “In defout_write: len=%d, str=‘%s’\n”, RSTRING(str)->len, RSTRING(str)->ptr);
rb_str_cat(self, RSTRING(str)->ptr, RSTRING(str)->len);
return Qnil;
}

static VALUE defout_cancel(VALUE self)
{
fprintf(stderr, “In defout_cancel\n”);
if (RSTRING(self)->len == 0) return Qnil;
RSTRING(self)->len = 0;
RSTRING(self)->ptr[0] = ‘\0’;
return Qnil;
}

static void init()
{
ruby_init();
#if RUBY_VERSION_CODE >= 160
ruby_init_loadpath();
#else
#if RUBY_VERSION_CODE >= 145
rb_ary_push(rb_load_path, rb_str_new2(“.”));
#endif
#endif
rb_defout = rb_str_new(“”, 0);
rb_io_binmode(rb_stdout); /* for mswin32 /
rb_define_singleton_method(rb_defout, “write”, (VALUE(
)(ANYARGS))&defout_write, 1);
rb_define_singleton_method(rb_defout, “cancel”, (VALUE(*)(ANYARGS))&defout_cancel, 0);
}

static void proc_args(int argc, char **argv)
{
ruby_script(argv[0]);
// Other stuff here for initializing FLTK…
}

int main(int argc, char **argv)
{
// fprintf(stderr, “Calling init…\n”);
init();
// fprintf(stderr, “Calling proc_args…\n”);
proc_args(argc, argv);
// fprintf(stderr, “Calling run…\n”);
Fl::run(); // This is my FLTK GUI… you might not have this,
// but you will need some kind of event loop or something.
// Note that my GUI has callbacks that call ‘ruby_eval’, below…
return 0;
}

VALUE ruby_eval(const char* str)
{
int state = 0;
fprintf(stderr, “Calling ruby: ‘%s’\n”, str);
VALUE val = rb_eval_string_protect(str, &state);
if (state == Qundef) {
fprintf(stderr, “ERROR: Undefined statement: ‘%s’\n”, str);
} else {
fprintf(stderr, “State=%d, return VALUE=%08lX\n”, state, val);
}
return val;
}

   Is this kind of operation possible?

Well, this is very quickly written

pigeon% cat a.c
#include <ruby.h>

static VALUE
aa_func(obj)
    VALUE obj;
{
    rb_p(rb_str_new2("I'm is ruby_func"));
    return obj;
}

int main()
{
    ruby_init();
    ruby_init_loadpath();
    rb_define_method(rb_cObject, "ruby_func", aa_func, 0);
    rb_p(rb_str_new2("before b.rb"));
    rb_load_protect(rb_str_new2("b.rb"), Qfalse, 0);
    rb_p(rb_str_new2("after b.rb"));
}
pigeon%

pigeon% cat b.rb
#!/usr/bin/ruby
p "before ruby_func"
ruby_func
p "after ruby_func"
pigeon%

pigeon% a.out
"before b.rb"
"before ruby_func"
"I'm is ruby_func"
"after ruby_func"
"after b.rb"
pigeon%

Guy Decoux

“Glenn M. Lewis” glenn@gmlewis.com wrote in message news:3DDD0A19.2060507@gmlewis.com

Johan Persson wrote:

Or at least, is there any documentation aviable on the subject?

Hi Johan!

I looked through a bunch of examples in the RAA, and here
is what I hacked together, and it seems to work… I’m just a newbie,
so take it all with a grain of salt…
– Glenn

/* code */

I don’t really know if this was what I was looking for, but thanks
anyway! I guess I’ll have to either hack my way through or just wait
till Ruby matures a lil bit before embedding it… :slight_smile:

-Johan