You may want to read about typemaps before going further -- this is an example of their use...

Say I want to wrap the following C code into Perl. I'll be showing how the typemaps in Swig help do this.

/* For Swig: takes parameter by reference, returns result in place */
void next_hailstone(int *BOTH);

void next_hailstone(int *n)
  return (n % 2 == 1) ? 3*n+1 : n/2;
The function takes one int and returns one int; most of the subtleties of typemaps don't apply.

We'd like to call it with Perl code like this:

# How many iterations to get to 1?
my $i = 0;
while ($n != 1) {
  $n = next_hailstone($n);

So we need to convert Perl (numerical) scalars into C ints and vice versa. Swig already knows how to do this, using its builtin typemaps (I omit much of the irrelevant parts of Swig's typemapping):

%typemap(perl5,in) int        *BOTH(int temp)
  temp = (int) SvIV($source);
  $target = &temp;
The part in curly brackets does the type conversion, and the rest passes information about the conversion to Swig. In other words, we're telling Swig that:
  • to pass a Perl number into the function, create a temporary temp, extract the integer value (IV) of the Perl scalar into temp, and pass the function the address of that temporary.

For output, we go the other way:

%typemap(perl5,argout) int    *BOTH
  /* make room on the Perl return stack */
  if (argvi >= items) {
  $target = sv_newmortal();   /* Scalar holding return */
  sv_setiv($target,(IV) *($source));
Most of the code is concerned with handling the details of variable return on the Perl stack. The line sv_setiv sets the Perl scalar holding the return value to the returned value from the C subroutine.

The above typemapping code is part of the standard Swig library, so you don't need to type it in. And once you have your typemap, all it takes to tell Swig to wrap next_hailstone() for use from Perl is the line

void next_hailstone(int *BOTH);
which explains the precise semantics of the int * argument.

Log in or registerto write something here or to contact authors.