Embedding, 'require' and extensions

I've basically taken the embedding example from pickaxeII and the only
thing I've added is for the Ruby program to do a 'require' of a file known
to exist in the library.

Here is the relevant part of the C-side code:
//summer.c
int main(void) {
  int value;
  int* next = Values;

  ruby_init();
  ruby_init_loadpath();
  ruby_script("embedded");
  rb_require("sum.rb"); //ruby script is sum.rb

  ruby_finalize();
  exit(0);
}
//end of summer.c

So the ruby_init_loadpath() should be setting up the loadpath correctly,
and I can confirm this by making the ruby script to be required (sum.rb)
like so:

  #sum.rb
  puts $:

Now if I run summer, I get:
  $ ./summer
  /usr/local/lib/ruby/site_ruby/1.8
  /usr/local/lib/ruby/site_ruby/1.8/i686-linux
  /usr/local/lib/ruby/site_ruby
  /usr/local/lib/ruby/1.8
  /usr/local/lib/ruby/1.8/i686-linux
  .

....Which looks fine.

Now, if I change sum.rb to:
  #sum.rb
  require 'openssl'

I get:
  $ ./summer
  ./sum.rb:2: [BUG] Segmentation fault
  ruby 1.8.2 (2004-07-29) [i686-linux]

  Aborted

Apparently, because require can't find the openssl library.

However, the openssl lib is there:
  $ irb
  irb(main):001:0> require 'openssl'
  => true

What gives? $: looks fine.

Another datapoint: if I change the require in sum.rb to:
  #sum.rb
  require 'ftools'

It seems to work. Is there a problem with require'ing extensions (like
openssl.so) this way? (seems to not work) If so, is there any way of
doing this?

Phil

Here is the relevant part of the C-side code:

You don't give the most important part : how do you build your
executable ?

You must use the value given in rbconfig.rb to build the command line, in
your case you've probably forgotten -rdynamic when you have compiled your
source.

Another thing

  rb_require("sum.rb"); //ruby script is sum.rb

You *must* protect any call to a ruby function which can generate an
error, with rb_protect(), otherwise ruby will crash

Guy Decoux

In article <200410301010.i9UAAFP29889@moulon.inra.fr>,

Here is the relevant part of the C-side code:

You don't give the most important part : how do you build your
executable ?

You must use the value given in rbconfig.rb to build the command line, in
your case you've probably forgotten -rdynamic when you have compiled your
source.

Here's how I built:
$ gcc -I/usr/local/lib/ruby/1.8/i686-linux -g -c -o summer.o summer.c
$ gcc -o summer summer.o -L/usr/local/lib/ruby/1.8/i686-linux -lruby-static -ldl -lm -lcrypt
-rdynamic

It didn't make any difference if I used rdynamic or not.

Another thing

  rb_require("sum.rb"); //ruby script is sum.rb

You *must* protect any call to a ruby function which can generate an
error, with rb_protect(), otherwise ruby will crash

Yes, I know. I was only doing a quick/small test before adding more.

Phil

···

ts <decoux@moulon.inra.fr> wrote:

$ gcc -I/usr/local/lib/ruby/1.8/i686-linux -g -c -o summer.o summer.c
$ gcc -o summer summer.o -L/usr/local/lib/ruby/1.8/i686-linux -lruby-static -ldl -lm -lcrypt
-rdynamic

It didn't make any difference if I used rdynamic or not.

Well, at moulon

svg% cat aa.c
#include <ruby.h>

static VALUE
tt()
{
    return rb_require("sum.rb");
}

int main()
{
  int value;

  ruby_init();
  ruby_init_loadpath();
  ruby_script("embedded");
  rb_protect(tt, Qnil, &value);
  if (value) {
      VALUE err = rb_inspect(rb_gv_get("$!"));
      fprintf(stderr, "ERR %s\n", StringValuePtr(err));
  }

  ruby_finalize();
  exit(0);
}
svg%

svg% cc -I. -I/usr/local/lib/ruby/1.8/i686-linux aa.c -L/usr/local/lib -lruby-static -ldl -lcrypt -lm
svg%

svg% ./a.out
ERR #<LoadError: /usr/local/lib/ruby/1.8/i686-linux/openssl.so: undefined symbol: rb_eRuntimeError - /usr/local/lib/ruby/1.8/i686-linux/openssl.so>
svg%

svg% cc -I. -I/usr/local/lib/ruby/1.8/i686-linux aa.c -L/usr/local/lib -lruby-static -ldl -lcrypt -lm -rdynamic
svg%

svg% ./a.out
svg%

Guy Decoux