I have two C extensions for Ruby (for a Rails app). I initialize these in application.rb with config.after_initialize.
Here is the first Class:
class Object
require 'inline'
inline do |builder|
builder.c <<-EOC
static VALUE
rb_obj_is_number(){
// code to return Qtrue or Qfalse
}
EOC
end
alias is_number rb_obj_is_number
end
Here is the second (which needs to use rb_obj_is_number() from above):
class Array
require 'inline'
inline do |builder|
builder.c <<-EOC
static VALUE
rb_ary_some_fun(){
double result = 0;
long i, len = RARRAY_LEN(self);
VALUE *c_arr = RARRAY_PTR(self);
for(i=0; i<len; i++) {
if ( TYPE(rb_obj_is_number(c_arr[i])) == T_TRUE ) {
result += NUM2DBL(c_arr[i]);
}
}
return rb_float_new(result);
}
EOC
end
alias some_fun rb_ary_some_fun
end
While trying to call a function from one file to another I get the following error:
dyld: lazy symbol binding failed: Symbol not found: _rb_obj_is_number
I guess this is because I did not include the first generated file in the second.
How can I do that in order to have rb_obj_is_number recognized by the compiler?
Your functions are declared as
staticin separate compilation units so of courserb_ary_some_funcannot seerb_obj_is_number. Two options immediately come to mind:One options is to put the C implementation of
rb_obj_is_numberin a String that is accessible to bothbuilder.ccalls. This will give you two copies of the function but:staticso you won’t have namespace issues.You’d have something like this:
That’s a big pile of kludge so I wouldn’t recommend it. There are probably cases where that approach makes sense though.
The right way to do this is to call
is_numberas a Ruby method from your C. Callingis_numberas a method allows it to be overridden, monkey patched, etc. just like any other method. You’d userb_funcallsomething like this:Also, I recommend that you use proper function signatures (i.e.
rb_obj_is_number(void)) to make sure your compiler doesn’t end up in K&R mode. You should also adjust your compiler’s warning flags so that it complains loudly about that sort of thing.