So here's what I have right now. The only thing that's missing is the
stuff to fix the last function.
%module unh_cmac
%include typemaps.i
#define ALBUS 65
#define RECTANGULAR 82
#define LINEAR 76
#define SPLINE 83
#define CUSTOM 67
#define VTRUE 1
#define VFALSE 0
%typemap(ruby,in) (int num_state, int *qnt_state) {
int i;
if (!rb_obj_is_kind_of($input,rb_cArray))
rb_raise(rb_eArgError, "Expected Array of Integers");
$1 = RARRAY($input)->len;
$2 = malloc($1*sizeof(int));
for (i=0; i<$1; ++i)
($2)[i] = NUM2INT(RARRAY($input)->ptr[i]);
}
%typemap(freearg) (int size, int *ary) {
if ($2) free($2);
}
%typemap(ruby,out) int {
if($1 == 0) {
$result = Qnil;
} else {
$result = INT2NUM($1);
}
}
int allocate_cmac(int num_state, int *qnt_state,
int num_resp, int num_cell,
int memory, int rfield_shape,
int collision_flag);
%typemap(ruby,in) (int *state) {
int i;
int length;
if (!rb_obj_is_kind_of($input,rb_cArray))
rb_raise(rb_eArgError, "Expected Array of Integers");
length = RARRAY($input)->len;
$1 = malloc(length*sizeof(int));
for (i=0; i<length; ++i)
($1)[i] = NUM2INT(RARRAY($input)->ptr[i]);
}
%typemap(freearg) (int *state) {
if ($1) free($1);
}
%typemap(ruby,in) (int *respns) {
int i;
int length;
if (!rb_obj_is_kind_of($input,rb_cArray))
rb_raise(rb_eArgError, "Expected Array of Integers");
length = RARRAY($input)->len;
$1 = malloc(length*sizeof(int));
for (i=0; i<length; ++i)
($1)[i] = NUM2INT(RARRAY($input)->ptr[i]);
}
%typemap(freearg) (int *respns) {
if ($1) free($1);
}
%typemap(ruby,out) int {
if($1 == 0) {
$result = Qfalse;
} else {
$result = Qtrue;
}
}
int train_cmac(int cmac_id, int *state, int *respns, int beta1, int beta2);
/* Need stuff here */
int cmac_response(int cmac_id, int *state, int *respns);
-Kurt
···
On Mon, 22 Nov 2004 13:09:03 -0600, Kurt Dresner <omega697@gmail.com> wrote:
Here are the actual functions I need to wrap:
/* This one allocates a cmac, which is the thing I'm going to be
using. I tell it how many
* states it has, how many responses it has, and some other
parameters. The typemap you
* provided I think will work rather well for this function.
*/
int allocate_cmac(int num_state, int *qnt_state,
int num_resp, int num_cell,
int memory, int rfield_shape,
int collision_flag);
/* With this function, I provide the ID of the cmac that was returned
to me in the allocate
* function. I then provide two arrays: the input states and the
desired responses. These
* have to be of the sizes num_state and num_resp from the last
function. I think a similar
* typemap will work just fine, since the C code presumably knows the
size of the arrays.
* I just won't provide it.
*/
int train_cmac(int cmac_id, int *state, int *respns, int beta1, int beta2);
/* This is the one I'm stuck on. I need to provide the ID, which will
work, and then an array
* of state ints. That will work too, as in the last one. Now,
however, I need to provide
* an array for the response. This array is then filled up with the
response. Two things are
* confusing me. I should probably do some sort of argout so I can
get both the int
* (success/failure) return value (which I can probably map to
true/nil right?) and the array
* return value. The thing is, I don't know how to get it to create a
Ruby array for this
* return value, since in the interface code, I don't know how big the
array is. The C code
* knows (presumably - I didn't write it). So I don't know how to
write the argout to take care
* of it. I have no idea what to do with this.
*/
int cmac_response(int cmac_id, int *state, int *respns);
Any ideas?
-Kurt
On Sun, 21 Nov 2004 22:58:07 +0900, Tobias Peters > <tpeters@invalid.uni-oldenburg.de> wrote:
> Kurt Dresner wrote:
>
>
> > Hi all,
> >
> > I'm trying to get SWIG to create a wrapper for some C code.
> > Specifically, there are several functions that take, as parameters, an
> > int* (they also take the length of the array). I don't know how to do
> > the typemap for this - I want to be able to write
> >
> > My_module.my_c_function([1,2,3])
> >
> > for the corresponding C function
> >
> > void my_c_function(int size, int* ary)
> >
> > Additionally, one of the functions takes an integer array as a
> > parameter, and I'd like it instead to return an array in Ruby (full of
> > Nums). I know how to get it to return the argument (instead of doing
> > the pointer passing thing), but then it just thinks I want to pass it
> > an integer instead of an array of integers.
> >
> > Anyone have any idea how to help me? Everything I've seen pertains to
> > char** and I'm not sure how to convert it to work how I want with
> > int*.
>
> Passing an array of integers from Ruby to C with SWIG requires
> multi-argument "in" and "freearg" typemaps:
>
> %typemap(ruby,in) (int size, int *ary) {
> int i;
> if (!rb_obj_is_kind_of($input,rb_cArray))
> rb_raise(rb_eArgError, "Expected Array of Integers");
> $1 = RARRAY($input)->len;
> $2 = malloc($1*sizeof(int));
> for (i=0; i<$1; ++i)
> ($2)[i] = NUM2INT(RARRAY($input)->ptr[i]);
> }
> %typemap(freearg) (int size, int *ary) {
> if ($2) free($2);
> }
>
> There's room for improvement in handling (or better: preventing)
> exceptions raised from NUM2INT (proper error message and deallocation of
> C array).
>
> Regarding output: It's not clear to me if you want in/out semantics or
> output only. I think you can achieve in/out with an additional
> multi-argument "argout" typemap. Output only implementation depends on
> which function is responsible for allocating/freeing the array and which
> is responsible for determining the array's size. You may need an
> additional "arginit" typemap for this one.
>
> Tobias
>
>