Ruby <-SWIG-> C arrays

Hi,

I am trying to wrap this function is C ro Ruby using SWIG:

typedef unsigned long uInt32
someFunction(uInt32 someArray[])

The array is simply some input. Calling the wrapped function in Ruby:

Wrapper.someFunction([1, 2, 3])

produces this error:

...in method 'someFunction', argument 1 of type 'uInt32 []' (TypeError)

Does this have anything to do with the argument being defined as 'uInt32
someArray[]' and not 'uInt32 *someArray'?

···

--
Posted via http://www.ruby-forum.com/.

Aureliano Buendia wrote:

typedef unsigned long uInt32
someFunction(uInt32 someArray)

The array is simply some input. Calling the wrapped function in Ruby:

Wrapper.someFunction([1, 2, 3])

produces this error:

..in method 'someFunction', argument 1 of type 'uInt32 ' (TypeError)

It looks like you require some typemap here to convert a ruby array of integers to a C array of longs. You probably want %typemap(in), which mangles Ruby function/method params to something that the C function can digest.

Your %typemap(in) will use the RARRAY($input)->len Ruby C macro to get the length of the incoming ruby array. $input is a placeholder for the ruby parameter being processed. Create a new empty uInt32.

Then, for each element in the Ruby array use the NUM2LONG macro to convert the Ruby integer to a C long, and add this to your uInt32. Lastly, assign the uInt32 to the special variable $1, which is a placeholder for the actual value that will be passed to the C function. SWIG will generate the appropriate wrapper code.

You will want to verify the types of the arguments passed in from ruby, using TYPE and T_ARRAY etc macros.

Suggest you re-read the following sections of the Ruby/SWIG documentation should be useful:

http://www.swig.org/Doc1.3/Ruby.html#Ruby_nn39

http://www.swig.org/Doc1.3/Ruby.html#Ruby_nn47

Sorry I can't give you a complete example, but I'm not a C programmer, just familiar with SWIG. Hopefully this will get you started.

alex

Hi,

In <2250e499a84aaf577be46b5e5ffd238a@ruby-forum.com>
  "Ruby <-SWIG-> C arrays" on Wed, 15 Nov 2006 02:04:14 +0900,

typedef unsigned long uInt32
someFunction(uInt32 someArray)

The array is simply some input. Calling the wrapped function in Ruby:

Wrapper.someFunction([1, 2, 3])

produces this error:

Here is a my answer:

  %module "Example";

  %inline %{
  typedef unsigned long uInt32;
  %}

  %typemap(in, numinputs=1) (uInt32 some_array, int length)
  {
    int i;

    $2 = RARRAY($input)->len;
    $1 = ALLOCA_N(uInt32, $2);

    for (i = 0; i < $2; i++) {
      $1[i] = NUM2INT(RARRAY($input)->ptr[i]);
    }
  };

  %inline %{
  uInt32
  some_function(uInt32 some_array, int length) {
    int i;
    uInt32 sum = 0;
    for (i = 0; i < length; i++) {
      sum += some_array[i];
    }
    return sum;
  }
  %}

Compile:
  % swig -ruby a.i && ruby -r mkmf -e 'create_makefile("Example")' && make

Test:
  % ruby -r Example -e 'p Example.some_function([1, 2, 3])'
  6

Thanks,

···

Aureliano Buendia <saveez@hotmail.com> wrote:
--
kou

Kouhei Sutou wrote:

In <2250e499a84aaf577be46b5e5ffd238a@ruby-forum.com>
  "Ruby <-SWIG-> C arrays" on Wed, 15 Nov 2006 02:04:14 +0900,
  

typedef unsigned long uInt32
someFunction(uInt32 someArray)
    

Here is a my answer:

    $2 = RARRAY($input)->len;

Note that RARRAY(x)->len is going away in future versions of Ruby. Use RARRAY_LEN(x) if you can. If you don't have it defined you can always supply it:

#ifndef RARRAY_LEN
# define RARRAY_LEN(x) RARRAY(x)->len
#endif

Roy

···

  Aureliano Buendia <saveez@hotmail.com> wrote: