SWIG question: how to return an array from C to Ruby?

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

require "data_reader"

true

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

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

> require "data_reader"
true
> 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

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!

···

On Thursday 09 August 2007 03:20:04 am Joachim (München) wrote:

--
Konrad Meyer <konrad@tylerc.org> http://konrad.sobertillnoon.com/