Ruby <-SWIG-> C arrays

A

Aureliano Buendia

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'?
 
A

Alex Fenton

Aureliano said:
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
 
K

Kouhei Sutou

Hi,

In <[email protected]>
"Ruby <-SWIG-> C arrays" on Wed, 15 Nov 2006 02:04:14 +0900,
Aureliano Buendia said:
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 = NUM2INT(RARRAY($input)->ptr);
}
};


%inline %{
uInt32
some_function(uInt32 some_array[], int length) {
int i;
uInt32 sum = 0;
for (i = 0; i < length; i++) {
sum += some_array;
}
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,
 
R

Roy Sutton

Kouhei said:
In <[email protected]>
"Ruby <-SWIG-> C arrays" on Wed, 15 Nov 2006 02:04:14 +0900,
Aureliano Buendia said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top