From: Kurt Dresner Date: 2004-11-23T04:09:08+09:00 Subject: Re: SWIG and Arrays (of ints) 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 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 > >