// This file shows how one can tell SWIG to remap a data-type and // process it as a special case. // // Writing type-maps is non-trivial. See perlguts(1) for all of the // gory details (fortunately, once you have a typemap that works, // you can reuse it over and over again). // %module argv // This tells SWIG to treat char ** as an array %typemap(perl5,in) char ** { AV *tempav; I32 len; int i; SV **tv; if (!SvROK($source)) croak("$source is not an array."); if (SvTYPE(SvRV($source)) != SVt_PVAV) croak("$source is not an array."); tempav = (AV*)SvRV($source); len = av_len(tempav); $target = (char **) malloc((len+2)*sizeof(char *)); for (i = 0; i <= len; i++) { tv = av_fetch(tempav, i, 0); $target[i] = (char *) SvPV(*tv,PL_na); } $target[i] = 0; }; // This cleans up our char ** array after the function call %typemap(perl5,freearg) char ** { free($source); } // Creates a new Perl array and places a char ** into it %typemap(perl5,out) char ** { AV *myav; SV **svs; int i = 0,len = 0; /* Figure out how many elements we have */ while ($source[len]) len++; svs = (SV **) malloc(len*sizeof(SV *)); for (i = 0; i < len ; i++) { svs[i] = sv_newmortal(); sv_setpv((SV*)svs[i],$source[i]); }; myav = av_make(len,svs); for (i = 0; i < len; i++) { /* SvREFCNT_dec(svs[i]); */ } free(svs); $target = newRV((SV*)myav); sv_2mortal($target); argvi++; /* This is critical! */ } %inline %{ int print_args(char **argv) { int i = 0; while (argv[i]) { printf("argv[%d] = %s\n", i,argv[i]); i++; } return i; } // Returns a char ** list char **get_args() { static char *values[] = { "Dave", "Mike", "Susan", "John", "Michelle", 0}; return &values[0]; } // A C++ class class Foo { public: Foo() { } ~Foo() { }; void output(char **names) { int i = 0; while(names[i]) { printf("names[%d] = %s\n",i,names[i]); i++; } } }; %}