I need to make some C functions available to Ruby. One of them sets an
array of doubles. I want to return this array to Ruby.
On the C side:
data_reader.c:
#include “hardwaredriver.h”
…
void read_data( double *data )
{
for( i=0; i<8; ++i )
data[i] = … // get values from hardware driver
}
On the Ruby side, I would like to obtain the following
irb> require “data_reader”
true
irb> arr = Data_reader.read_data
[ 0.0, 0.1, … ] # arr now contains eight Floats
Question 1:
Do I understand correctly that there are basically two different ways
to proceed ?:
(a) wrapping the C code with SWIG,
(b) converting the C code to an explicit Ruby extension as
described in the Book: http://www.rubycentral.com/pickaxe/ext_ruby.html
IF the answer is yes, THEN
Question 2:
How do I return an array through C->SWIG-> Ruby ?
Web search gave me some hints on how to do it in the opposite
direction, using typemap(in); but it seems not trivial to invert
to typemap(out).
Thanks in advance, Joachim
On Thursday 09 August 2007 03:20:04 am Joachim (München) wrote:
for( i=0; i<8; ++i )
Question 1:
Do I understand correctly that there are basically two different ways
to proceed ?:
(a) wrapping the C code with SWIG,
(b) converting the C code to an explicit Ruby extension as
described in the Book: http://www.rubycentral.com/pickaxe/ext_ruby.html
IF the answer is yes, THEN
While I don’t know much (anything) about SWIG, C code needs to be
wrapped
as an extension to Ruby or indirectly wrapped via Inline for it to be
used
by ruby code.
Question 2:
How do I return an array through C->SWIG-> Ruby ?
Web search gave me some hints on how to do it in the opposite
direction, using typemap(in); but it seems not trivial to invert
to typemap(out).
Thanks in advance, Joachim
I’d recommend Inline for this, as it provides nice ruby->C parameter
conversions. To return ruby array data, you need a variable of type
VALUE,
which is a generic ruby object container. It’s also probably easiest if
you
know how long the array will be in advance (in fact I don’t know what to
do
otherwise).
ex:
#define ARR_LEN 31
VALUE ary;
double data[ARR_LEN];
… /* do your hw->data[] processing here */
ary = rb_ary_new2(ARR_LEN);
for(i = 0; i < ARR_LEN; i++)
RARRAY(ary)->ptr[i] = rb_float_new(data[i]);
RARRAY(ary)->len = ARR_LEN;
return ary;
Something like that ought to do the trick. Happy ruby-ing!