Fwd: [mapserver-dev] SWIG - perl array -> char **

Alex Rice alex_rice at arc.to
Sat Aug 10 13:20:35 EDT 2002


I have confirmed that this works properly if w/ SWIG 1.1 you 
append the following typemap to swig_lib/perl5/typemaps.i.

Note in SWIG 1.3 the macro na changes to PL_na. --Alex


// --------------------------------------------------------------------
// Special types
//
// --------------------------------------------------------------------

// A common problem in many C programs is the processing of 
command line arguments, which are usually passed in an array of 
NULL terminated strings. The following SWIG interface file allows 
a Perl5 array reference to be used as a char ** datatype.

%module argv

// This tells SWIG to treat char ** as a special case
%typemap(perl5,in) char ** {
         AV *tempav;
         I32 len;
         int i;
         SV  **tv;
         if (!SvROK($source))
             croak("$source is not a reference.");
         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,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);
         free(svs);
        $target = newRV((SV*)myav);
        sv_2mortal($target);
}


Begin forwarded message:

> From: Alex Rice <alex_rice at arc.to>
> Date: Fri Aug 09, 2002  11:14:21  PM US/Mountain
> To: mapserver-dev at lists.gis.umn.edu
> Subject: [mapserver-dev] SWIG - perl array -> char **
> X-Mailer: Apple Mail (2.482)
>
>
> I think I found a problem in the the SWIGing of some functions in 
> Perl mapscript. I am using the  msProcess*Template() functions 
> from perl mapscript. The function returns
>
> Type error in argument 3 of mapObj_processTemplate. Expected 
> charPtrPtr. at /Library/Perl/darwin/mapscript.pm line 2674.
>
> I think argument 3 is the array of tagNames. Here is the calling 
> perl code:
>
> my @tagNames = keys(%tags);
> my @tagValues = values(%tags);
> my $res = $mapObj->processTemplate($mapscript::MS_TRUE,
>                                    \@tagNames,
>                                    \@tagValues,
>                                    $#tagNames + 1);
>
> The SWIG configuration is for this function is:
>
> char *processTemplate(int bGenerateImages, char **names, char 
> **values, int numentries) {
>       return msProcessTemplate(self, bGenerateImages, names, 
> values, numentries);
> }
>
> We are missing in mapscript.i needs some special typemap setup to 
> be able to transform a perl array into char **.  See "Converting 
> a Perl5 array to a char **" at 
> http://www.swig.org/Doc1.1/HTML/Perl5.html#n14
>
> I was going to try to try this out and patch mapserver.i myself, 
> but I don't have SWIG. Also I've never used SWIG before and it's 
> a pretty big scary looking package. Anyways what version of SWIG 
> are you all running?
>
> P.S.  the same problem seems to apply to processLegendTemplate() 
> and processQueryTemplate();
>
> Alex Rice, Software Developer
> Architectural Research Consultants, Inc.
> alex_rice at arc.to
> alrice at swcp.com
>
>
>
>




More information about the mapserver-dev mailing list