1 /* ----------------------------------------------------------------------------- 2 * typemaps.swg 3 * 4 * SWIG Library file containing the main typemap code to support Lua modules. 5 * ----------------------------------------------------------------------------- */ 6 7 /* ----------------------------------------------------------------------------- 8 * Basic inout typemaps 9 * ----------------------------------------------------------------------------- */ 10 /* 11 These provide the basic ability for passing in & out of standard numeric data types 12 (int,long,float,double, etc) 13 14 The basic code looks like this: 15 16 %typemap(in,checkfn="lua_isnumber") int *INPUT(int temp), int &INPUT(int temp) 17 %{ temp = (int)lua_tonumber(L,$input); 18 $1 = &temp; %} 19 20 %typemap(in, numinputs=0) int *OUTPUT (int temp) 21 %{ $1 = &temp; %} 22 23 %typemap(argout) int *OUTPUT 24 %{ lua_pushnumber(L, (double) *$1); SWIG_arg++;%} 25 26 %typemap(in) int *INOUT = int *INPUT; 27 %typemap(argout) int *INOUT = int *OUTPUT; 28 29 However the code below is a mixture of #defines & such, so nowhere as easy to read 30 31 To make you code work correctly its not just a matter of %including this file 32 You also have to give SWIG the hints on which to use where 33 34 eg 35 extern int add_pointer(int* a1,int* a2); // a1 & a2 are pointer values to be added 36 extern void swap(int* s1, int* s2); // does the swap 37 38 You will need to either change the argument names 39 extern int add_pointer(int* INPUT,int* INPUT); 40 41 or provide a %apply statement 42 43 %apply int* INOUT{ int *s1, int *s2 }; 44 // if SWIG sees int* s1, int* s2, assume they are inout params 45 */ 46 47 48 %define SWIG_NUMBER_TYPEMAP(TYPE) 49 %typemap(in,checkfn="lua_isnumber") TYPE *INPUT($*ltype temp), TYPE &INPUT($*ltype temp) 50 %{ temp = ($*ltype)lua_tonumber(L,$input); 51 $1 = &temp; %} 52 %typemap(in, numinputs=0) TYPE *OUTPUT ($*ltype temp) 53 %{ $1 = &temp; %} 54 %typemap(argout) TYPE *OUTPUT 55 %{ lua_pushnumber(L, (lua_Number) *$1); SWIG_arg++;%} 56 %typemap(in) TYPE *INOUT = TYPE *INPUT; 57 %typemap(argout) TYPE *INOUT = TYPE *OUTPUT; 58 %typemap(in) TYPE &OUTPUT = TYPE *OUTPUT; 59 %typemap(argout) TYPE &OUTPUT = TYPE *OUTPUT; 60 %typemap(in) TYPE &INOUT = TYPE *INPUT; 61 %typemap(argout) TYPE &INOUT = TYPE *OUTPUT; 62 // const version (the $*ltype is the basic number without ptr or const's) 63 %typemap(in,checkfn="lua_isnumber") const TYPE *INPUT($*ltype temp) 64 %{ temp = ($*ltype)lua_tonumber(L,$input); 65 $1 = &temp; %} 66 %enddef 67 68 // now the code 69 SWIG_NUMBER_TYPEMAP(unsigned char); SWIG_NUMBER_TYPEMAP(signed char); 70 71 SWIG_NUMBER_TYPEMAP(short); SWIG_NUMBER_TYPEMAP(unsigned short); SWIG_NUMBER_TYPEMAP(signed short); 72 SWIG_NUMBER_TYPEMAP(int); SWIG_NUMBER_TYPEMAP(unsigned int); SWIG_NUMBER_TYPEMAP(signed int); 73 SWIG_NUMBER_TYPEMAP(long); SWIG_NUMBER_TYPEMAP(unsigned long); SWIG_NUMBER_TYPEMAP(signed long); 74 SWIG_NUMBER_TYPEMAP(float); 75 SWIG_NUMBER_TYPEMAP(double); 76 SWIG_NUMBER_TYPEMAP(enum SWIGTYPE); 77 // also for long longs's 78 SWIG_NUMBER_TYPEMAP(long long); SWIG_NUMBER_TYPEMAP(unsigned long long); SWIG_NUMBER_TYPEMAP(signed long long); 79 80 // note we dont do char, as a char* is probably a string not a ptr to a single char 81 82 // similar for booleans 83 %typemap(in,checkfn="lua_isboolean") bool *INPUT(bool temp), bool &INPUT(bool temp) 84 %{ temp = (lua_toboolean(L,$input)!=0); 85 $1 = &temp; %} 86 87 %typemap(in, numinputs=0) bool *OUTPUT (bool temp),bool &OUTPUT (bool temp) 88 %{ $1 = &temp; %} 89 90 %typemap(argout) bool *OUTPUT,bool &OUTPUT 91 %{ lua_pushboolean(L, (int)((*$1)!=0)); SWIG_arg++;%} 92 93 %typemap(in) bool *INOUT = bool *INPUT; 94 %typemap(argout) bool *INOUT = bool *OUTPUT; 95 %typemap(in) bool &INOUT = bool &INPUT; 96 %typemap(argout) bool &INOUT = bool &OUTPUT; 97 98 /* ----------------------------------------------------------------------------- 99 * Basic Array typemaps 100 * ----------------------------------------------------------------------------- */ 101 /* 102 I have no idea why this kind of code does not exist in SWIG as standard, 103 but here is it. 104 This code will convert to/from 1D numeric arrays. 105 In order to reduce code bloat, there are a few macros 106 and quite a few functions defined 107 (unfortunately this makes it a lot less clear) 108 109 assuming we have functions 110 void process_array(int arr[3]); // nice fixed size array 111 void process_var_array(float arr[],int len); // variable sized array 112 void process_var_array_inout(double* arr,int len); // variable sized array 113 // data passed in & out 114 void process_enum_inout_array_var(enum Days *arrinout, int len); // using enums 115 void return_array_5(int arrout[5]); // out array only 116 117 in order to wrap them correctly requires a typemap 118 119 // inform SWIG of the correct typemap 120 // For fixed length, you must specify it as <type> INPUT[ANY] 121 %apply (int INPUT[ANY]) {(int arr[3])}; 122 // variable length arrays are just the same 123 %apply (float INPUT[],int) {(float arr[],int len)}; 124 // it is also ok, to map the TYPE* instead of a TYPE[] 125 %apply (double *INOUT,int) {(double arr*,int len)}; 126 // for the enum's you must use enum SWIGTYPE 127 %apply (enum SWIGTYPE *INOUT,int) {(enum Days *arrinout, int len)}; 128 // fixed length out if also fine 129 %apply (int OUTPUT[ANY]) {(int arrout[5])}; 130 131 Generally, you could use %typemap(...)=... 132 but the %apply is neater & easier 133 134 a few things of note: 135 * all Lua tables are indexed from 1, all C/C++ arrays are indexed from 0 136 therefore t={6,5,3} -- t[1]==6, t[2]==5, t[3]==3 137 when passed to process_array(int arr[3]) becomes 138 arr[0]==6, arr[1]==5, arr[2]==3 139 * for OUTPUT arrays, no array need be passed in, the fn will return a Lua table 140 so for the above mentioned return_array_5() would look like 141 arr=return_array_5() -- no parameters passed in 142 * for INOUT arrays, a table must be passed in, and a new table will be returned 143 (this is consistent with the way that numbers are processed) 144 if you want just use 145 arr={...} 146 arr=process_var_array_inout(arr) -- arr is replaced by the new version 147 148 The following are not yet supported: 149 * variable length output only array (inout works ok) 150 * multidimensional arrays 151 * arrays of objects/structs 152 * arrays of pointers 153 154 */ 155 156 /* 157 The internals of the array management stuff 158 helper fns/macros 159 SWIG_ALLOC_ARRAY(TYPE,LEN) // returns a typed array TYPE[LEN] 160 SWIG_FREE_ARRAY(PTR) // delete the ptr (if not zero) 161 162 // counts the specified table & gets the size 163 // integer version 164 int SWIG_itable_size(lua_State* L, int index); 165 // other version 166 int SWIG_table_size(lua_State* L, int index); 167 168 SWIG_DECLARE_TYPEMAP_ARR_FN(NAME,TYPE) 169 // this fn declares up 4 functions for helping to read/write tables 170 // these can then be called by the macros ... 171 // all assume the table is an integer indexes from 1 172 // but the C array is a indexed from 0 173 // created a fixed size array, reads the specified table 174 // and then fills the array with numbers 175 // returns ptr to the array if ok, or 0 for error 176 // (also pushes a error message to the stack) 177 TYPE* SWIG_get_NAME_num_array_fixed(lua_State* L, int index, int size); 178 // as per SWIG_get_NAME_num_array_fixed() 179 // but reads the entire table & creates an array of the correct size 180 // (if the table is empty, it returns an error rather than a zero length array) 181 TYPE* SWIG_get_NAME_num_array_var(lua_State* L, int index, int* size); 182 // writes a table to Lua with all the specified numbers 183 void SWIG_write_NAME_num_array(lua_State* L,TYPE *array,int size); 184 // read the specified table, and fills the array with numbers 185 // returns 1 of ok (only fails if it doesnt find numbers) 186 // helper fn (called by SWIG_get_NAME_num_array_*() fns) 187 int SWIG_read_NAME_num_array(lua_State* L,int index,TYPE *array,int size); 188 189 */ 190 191 /* Reported that you don't need to check for NULL for delete & free 192 There probably is some compiler that its not true for, so the code is left here just in case. 193 #ifdef __cplusplus 194 #define SWIG_ALLOC_ARRAY(TYPE,LEN) new TYPE[LEN] 195 #define SWIG_FREE_ARRAY(PTR) if(PTR){delete[] PTR;} 196 #else 197 #define SWIG_ALLOC_ARRAY(TYPE,LEN) (TYPE *)malloc(LEN*sizeof(TYPE)) 198 #define SWIG_FREE_ARRAY(PTR) if(PTR){free(PTR);} 199 #endif 200 */ 201 %{ 202 #ifdef __cplusplus /* generic alloc/dealloc fns*/ 203 #define SWIG_ALLOC_ARRAY(TYPE,LEN) new TYPE[LEN] 204 #define SWIG_FREE_ARRAY(PTR) delete[] PTR 205 #else 206 #define SWIG_ALLOC_ARRAY(TYPE,LEN) (TYPE *)malloc(LEN*sizeof(TYPE)) 207 #define SWIG_FREE_ARRAY(PTR) free(PTR) 208 #endif 209 /* counting the size of arrays:*/ 210 SWIGINTERN int SWIG_itable_size(lua_State* L, int index) 211 { 212 int n=0; 213 while(1){ 214 lua_rawgeti(L,index,n+1); 215 if (lua_isnil(L,-1))break; 216 ++n; 217 lua_pop(L,1); 218 } 219 lua_pop(L,1); 220 return n; 221 } 222 223 SWIGINTERN int SWIG_table_size(lua_State* L, int index) 224 { 225 int n=0; 226 lua_pushnil(L); /* first key*/ 227 while (lua_next(L, index) != 0) { 228 ++n; 229 lua_pop(L, 1); /* removes `value'; keeps `key' for next iteration*/ 230 } 231 return n; 232 } 233 234 /* super macro to declare array typemap helper fns */ 235 #define SWIG_DECLARE_TYPEMAP_ARR_FN(NAME,TYPE)\ 236 SWIGINTERN int SWIG_read_##NAME##_num_array(lua_State* L,int index,TYPE *array,int size){\ 237 int i;\ 238 for (i = 0; i < size; i++) {\ 239 lua_rawgeti(L,index,i+1);\ 240 if (lua_isnumber(L,-1)){\ 241 array[i] = (TYPE)lua_tonumber(L,-1);\ 242 } else {\ 243 lua_pop(L,1);\ 244 return 0;\ 245 }\ 246 lua_pop(L,1);\ 247 }\ 248 return 1;\ 249 }\ 250 SWIGINTERN TYPE* SWIG_get_##NAME##_num_array_fixed(lua_State* L, int index, int size){\ 251 TYPE *array;\ 252 if (!lua_istable(L,index) || SWIG_itable_size(L,index) != size) {\ 253 SWIG_Lua_pushferrstring(L,"expected a table of size %d",size);\ 254 return 0;\ 255 }\ 256 array=SWIG_ALLOC_ARRAY(TYPE,size);\ 257 if (!SWIG_read_##NAME##_num_array(L,index,array,size)){\ 258 SWIG_Lua_pusherrstring(L,"table must contain numbers");\ 259 SWIG_FREE_ARRAY(array);\ 260 return 0;\ 261 }\ 262 return array;\ 263 }\ 264 SWIGINTERN TYPE* SWIG_get_##NAME##_num_array_var(lua_State* L, int index, int* size)\ 265 {\ 266 TYPE *array;\ 267 if (!lua_istable(L,index)) {\ 268 SWIG_Lua_pusherrstring(L,"expected a table");\ 269 return 0;\ 270 }\ 271 *size=SWIG_itable_size(L,index);\ 272 if (*size<1){\ 273 SWIG_Lua_pusherrstring(L,"table appears to be empty");\ 274 return 0;\ 275 }\ 276 array=SWIG_ALLOC_ARRAY(TYPE,*size);\ 277 if (!SWIG_read_##NAME##_num_array(L,index,array,*size)){\ 278 SWIG_Lua_pusherrstring(L,"table must contain numbers");\ 279 SWIG_FREE_ARRAY(array);\ 280 return 0;\ 281 }\ 282 return array;\ 283 }\ 284 SWIGINTERN void SWIG_write_##NAME##_num_array(lua_State* L,TYPE *array,int size){\ 285 int i;\ 286 lua_newtable(L);\ 287 for (i = 0; i < size; i++){\ 288 lua_pushnumber(L,(lua_Number)array[i]);\ 289 lua_rawseti(L,-2,i+1);/* -1 is the number, -2 is the table*/ \ 290 }\ 291 } 292 %} 293 294 /* 295 This is one giant macro to define the typemaps & the helpers 296 for array handling 297 */ 298 %define SWIG_TYPEMAP_NUM_ARR(NAME,TYPE) 299 %{SWIG_DECLARE_TYPEMAP_ARR_FN(NAME,TYPE);%} 300 301 // fixed size array's 302 %typemap(in) TYPE INPUT[ANY] 303 %{ $1 = SWIG_get_##NAME##_num_array_fixed(L,$input,$1_dim0); 304 if (!$1) SWIG_fail;%} 305 306 %typemap(freearg) TYPE INPUT[ANY] 307 %{ SWIG_FREE_ARRAY($1);%} 308 309 // variable size array's 310 %typemap(in) (TYPE *INPUT,int) 311 %{ $1 = SWIG_get_##NAME##_num_array_var(L,$input,&$2); 312 if (!$1) SWIG_fail;%} 313 314 %typemap(freearg) (TYPE *INPUT,int) 315 %{ SWIG_FREE_ARRAY($1);%} 316 317 // out fixed arrays 318 %typemap(in,numinputs=0) TYPE OUTPUT[ANY] 319 %{ $1 = SWIG_ALLOC_ARRAY(TYPE,$1_dim0); %} 320 321 %typemap(argout) TYPE OUTPUT[ANY] 322 %{ SWIG_write_##NAME##_num_array(L,$1,$1_dim0); SWIG_arg++; %} 323 324 %typemap(freearg) TYPE OUTPUT[ANY] 325 %{ SWIG_FREE_ARRAY($1); %} 326 327 // inout fixed arrays 328 %typemap(in) TYPE INOUT[ANY]=TYPE INPUT[ANY]; 329 %typemap(argout) TYPE INOUT[ANY]=TYPE OUTPUT[ANY]; 330 %typemap(freearg) TYPE INOUT[ANY]=TYPE INPUT[ANY]; 331 // inout variable arrays 332 %typemap(in) (TYPE *INOUT,int)=(TYPE *INPUT,int); 333 %typemap(argout) (TYPE *INOUT,int) 334 %{ SWIG_write_##NAME##_num_array(L,$1,$2); SWIG_arg++; %} 335 %typemap(freearg) (TYPE *INOUT,int)=(TYPE *INPUT,int); 336 337 // TODO out variable arrays (is there a standard form for such things?) 338 339 // referencing so that (int *INPUT,int) and (int INPUT[],int) are the same 340 %typemap(in) (TYPE INPUT[],int)=(TYPE *INPUT,int); 341 %typemap(freearg) (TYPE INPUT[],int)=(TYPE *INPUT,int); 342 343 %enddef 344 345 // the following line of code 346 // declares the C helper fns for the array typemaps 347 // as well as defining typemaps for 348 // fixed len arrays in & out, & variable length arrays in 349 350 SWIG_TYPEMAP_NUM_ARR(schar,signed char); 351 SWIG_TYPEMAP_NUM_ARR(uchar,unsigned char); 352 SWIG_TYPEMAP_NUM_ARR(int,int); 353 SWIG_TYPEMAP_NUM_ARR(uint,unsigned int); 354 SWIG_TYPEMAP_NUM_ARR(short,short); 355 SWIG_TYPEMAP_NUM_ARR(ushort,unsigned short); 356 SWIG_TYPEMAP_NUM_ARR(long,long); 357 SWIG_TYPEMAP_NUM_ARR(ulong,unsigned long); 358 SWIG_TYPEMAP_NUM_ARR(float,float); 359 SWIG_TYPEMAP_NUM_ARR(double,double); 360 361 // again enums are a problem so they need their own type 362 // we use the int conversion routine & recast it 363 %typemap(in) enum SWIGTYPE INPUT[ANY] 364 %{ $1 = ($ltype)SWIG_get_int_num_array_fixed(L,$input,$1_dim0); 365 if (!$1) SWIG_fail;%} 366 367 %typemap(freearg) enum SWIGTYPE INPUT[ANY] 368 %{ SWIG_FREE_ARRAY($1);%} 369 370 // variable size arrays 371 %typemap(in) (enum SWIGTYPE *INPUT,int) 372 %{ $1 = ($ltype)SWIG_get_int_num_array_var(L,$input,&$2); 373 if (!$1) SWIG_fail;%} 374 375 %typemap(freearg) (enum SWIGTYPE *INPUT,int) 376 %{ SWIG_FREE_ARRAY($1);%} 377 378 // out fixed arrays 379 %typemap(in,numinputs=0) enum SWIGTYPE OUTPUT[ANY] 380 %{ $1 = SWIG_ALLOC_ARRAY(enum SWIGTYPE,$1_dim0); %} 381 382 %typemap(argout) enum SWIGTYPE OUTPUT[ANY] 383 %{ SWIG_write_int_num_array(L,(int*)$1,$1_dim0); SWIG_arg++; %} 384 385 %typemap(freearg) enum SWIGTYPE OUTPUT[ANY] 386 %{ SWIG_FREE_ARRAY($1); %} 387 388 // inout fixed arrays 389 %typemap(in) enum SWIGTYPE INOUT[ANY]=enum SWIGTYPE INPUT[ANY]; 390 %typemap(argout) enum SWIGTYPE INOUT[ANY]=enum SWIGTYPE OUTPUT[ANY]; 391 %typemap(freearg) enum SWIGTYPE INOUT[ANY]=enum SWIGTYPE INPUT[ANY]; 392 // inout variable arrays 393 %typemap(in) (enum SWIGTYPE *INOUT,int)=(enum SWIGTYPE *INPUT,int); 394 %typemap(argout) (enum SWIGTYPE *INOUT,int) 395 %{ SWIG_write_int_num_array(L,(int*)$1,$2); SWIG_arg++; %} 396 %typemap(freearg) (enum SWIGTYPE *INOUT,int)=(enum SWIGTYPE *INPUT,int); 397 398 399 /* Surprisingly pointer arrays are easier: 400 this is because all ptr arrays become void** 401 so only a few fns are needed & a few casts 402 403 The function defined are 404 // created a fixed size array, reads the specified table 405 // and then fills the array with pointers (checking the type) 406 // returns ptr to the array if ok, or 0 for error 407 // (also pushes a error message to the stack) 408 void** SWIG_get_ptr_array_fixed(lua_State* L, int index, int size,swig_type_info *type); 409 // as per SWIG_get_ptr_array_fixed() 410 // but reads the entire table & creates an array of the correct size 411 // (if the table is empty, it returns an error rather than a zero length array) 412 void** SWIG_get_ptr_array_var(lua_State* L, int index, int* size,swig_type_info *type); 413 // writes a table to Lua with all the specified pointers 414 // all pointers have the ownership value 'own' (normally 0) 415 void SWIG_write_ptr_array(lua_State* L,void **array,int size,int own); 416 // read the specified table, and fills the array with ptrs 417 // returns 1 of ok (only fails if it doesn't find correct type of ptrs) 418 // helper fn (called by SWIG_get_ptr_array_*() fns) 419 int SWIG_read_ptr_array(lua_State* L,int index,void **array,int size,swig_type_info *type); 420 421 The key thing to remember is that it is assumed that there is no 422 modification of pointers ownership in the arrays 423 424 eg A fn: 425 void pointers_in(TYPE* arr[],int len); 426 will make copies of the pointer into a temp array and then pass it into the fn 427 Lua does not remember that this fn held the pointers, so it is not safe to keep 428 these pointers until later 429 430 eg A fn: 431 void pointers_out(TYPE* arr[3]); 432 will return a table containing three pointers 433 however these pointers are NOT owned by Lua, merely borrowed 434 so if the C/C++ frees then Lua is not aware 435 436 */ 437 438 %{ 439 SWIGINTERN int SWIG_read_ptr_array(lua_State* L,int index,void **array,int size,swig_type_info *type){ 440 int i; 441 for (i = 0; i < size; i++) { 442 lua_rawgeti(L,index,i+1); 443 if (!lua_isuserdata(L,-1) || SWIG_ConvertPtr(L,-1,&array[i],type,0)==-1){ 444 lua_pop(L,1); 445 return 0; 446 } 447 lua_pop(L,1); 448 } 449 return 1; 450 } 451 SWIGINTERN void** SWIG_get_ptr_array_fixed(lua_State* L, int index, int size,swig_type_info *type){ 452 void **array; 453 if (!lua_istable(L,index) || SWIG_itable_size(L,index) != size) { 454 SWIG_Lua_pushferrstring(L,"expected a table of size %d",size); 455 return 0; 456 } 457 array=SWIG_ALLOC_ARRAY(void*,size); 458 if (!SWIG_read_ptr_array(L,index,array,size,type)){ 459 SWIG_Lua_pushferrstring(L,"table must contain pointers of type %s",type->name); 460 SWIG_FREE_ARRAY(array); 461 return 0; 462 } 463 return array; 464 } 465 SWIGINTERN void** SWIG_get_ptr_array_var(lua_State* L, int index, int* size,swig_type_info *type){ 466 void **array; 467 if (!lua_istable(L,index)) { 468 SWIG_Lua_pusherrstring(L,"expected a table"); 469 return 0; 470 } 471 *size=SWIG_itable_size(L,index); 472 if (*size<1){ 473 SWIG_Lua_pusherrstring(L,"table appears to be empty"); 474 return 0; 475 } 476 array=SWIG_ALLOC_ARRAY(void*,*size); 477 if (!SWIG_read_ptr_array(L,index,array,*size,type)){ 478 SWIG_Lua_pushferrstring(L,"table must contain pointers of type %s",type->name); 479 SWIG_FREE_ARRAY(array); 480 return 0; 481 } 482 return array; 483 } 484 SWIGINTERN void SWIG_write_ptr_array(lua_State* L,void **array,int size,swig_type_info *type,int own){ 485 int i; 486 lua_newtable(L); 487 for (i = 0; i < size; i++){ 488 SWIG_NewPointerObj(L,array[i],type,own); 489 lua_rawseti(L,-2,i+1);/* -1 is the number, -2 is the table*/ 490 } 491 } 492 %} 493 494 // fixed size array's 495 %typemap(in) SWIGTYPE* INPUT[ANY] 496 %{ $1 = ($ltype)SWIG_get_ptr_array_fixed(L,$input,$1_dim0,$*1_descriptor); 497 if (!$1) SWIG_fail;%} 498 499 %typemap(freearg) SWIGTYPE* INPUT[ANY] 500 %{ SWIG_FREE_ARRAY($1);%} 501 502 // variable size array's 503 %typemap(in) (SWIGTYPE **INPUT,int) 504 %{ $1 = ($ltype)SWIG_get_ptr_array_var(L,$input,&$2,$*1_descriptor); 505 if (!$1) SWIG_fail;%} 506 507 %typemap(freearg) (SWIGTYPE **INPUT,int) 508 %{ SWIG_FREE_ARRAY($1);%} 509 510 // out fixed arrays 511 %typemap(in,numinputs=0) SWIGTYPE* OUTPUT[ANY] 512 %{ $1 = SWIG_ALLOC_ARRAY($*1_type,$1_dim0); %} 513 514 %typemap(argout) SWIGTYPE* OUTPUT[ANY] 515 %{ SWIG_write_ptr_array(L,(void**)$1,$1_dim0,$*1_descriptor,0); SWIG_arg++; %} 516 517 %typemap(freearg) SWIGTYPE* OUTPUT[ANY] 518 %{ SWIG_FREE_ARRAY($1); %} 519 520 // inout fixed arrays 521 %typemap(in) SWIGTYPE* INOUT[ANY]=SWIGTYPE* INPUT[ANY]; 522 %typemap(argout) SWIGTYPE* INOUT[ANY]=SWIGTYPE* OUTPUT[ANY]; 523 %typemap(freearg) SWIGTYPE* INOUT[ANY]=SWIGTYPE* INPUT[ANY]; 524 // inout variable arrays 525 %typemap(in) (SWIGTYPE** INOUT,int)=(SWIGTYPE** INPUT,int); 526 %typemap(argout) (SWIGTYPE** INOUT,int) 527 %{ SWIG_write_ptr_array(L,(void**)$1,$2,$*1_descriptor,0); SWIG_arg++; %} 528 %typemap(freearg) (SWIGTYPE**INOUT,int)=(SWIGTYPE**INPUT,int); 529 530 /* ----------------------------------------------------------------------------- 531 * Pointer-Pointer typemaps 532 * ----------------------------------------------------------------------------- */ 533 /* 534 This code is to deal with the issue for pointer-pointer's 535 In particular for factory methods. 536 537 for example take the following code segment: 538 539 struct iMath; // some structure 540 int Create_Math(iMath** pptr); // its factory (assume it mallocs) 541 542 to use it you might have the following C code: 543 544 iMath* ptr; 545 int ok; 546 ok=Create_Math(&ptr); 547 // do things with ptr 548 //... 549 free(ptr); 550 551 With the following SWIG code 552 %apply SWIGTYPE** OUTPUT{iMath **pptr }; 553 554 You can get natural wrapping in Lua as follows: 555 ok,ptr=Create_Math() -- ptr is a iMath* which is returned with the int 556 ptr=nil -- the iMath* will be GC'ed as normal 557 */ 558 559 %typemap(in,numinputs=0) SWIGTYPE** OUTPUT ($*ltype temp) 560 %{ temp = ($*ltype)0; 561 $1 = &temp; %} 562 %typemap(argout) SWIGTYPE** OUTPUT 563 %{SWIG_NewPointerObj(L,*$1,$*descriptor,1); SWIG_arg++; %} 564 565