Kurt Dresner
11/22/2004 8:50:00 PM
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
> >
> >
>