Google

SWIG/Examples/perl5/pointer/

Simple Pointer Handling

$Header: /cvs/projects/SWIG/Examples/perl5/pointer/index.html,v 1.1 2000/09/02 19:18:32 beazley Exp $

This example illustrates a couple of techniques for handling simple pointers in SWIG. The prototypical example is a C function that operates on pointers such as this:

void add(int *x, int *y, int *r) { 
    *r = *x + *y;
}
By default, SWIG wraps this function exactly as specified and creates an interface that expects pointer objects for arguments. The only problem is how does one go about creating these objects from a script?

Possible Solutions

  • Write some helper functions to explicitly create objects. For example:
    int *new_int(int ivalue) {
      int *i = (int *) malloc(sizeof(ivalue));
      *i = ivalue;
      return i;
    }
    int get_int(int *i) {
      return *i;
    }
    
    void delete_int(int *i) {
      free(i);
    }
    
    Now, in a script you would do this:
    $a = new_int(37);
    $b = new_int(42);
    $c = new_int(0):
    add($a,$b,$c);
    $r = get_int($c);
    print "Result = $r\n";
    delete_int($a);
    delete_int($b);
    delete_int($c);
    

  • Use the SWIG pointer library. For example, in the interface file you would do this:
    %include "pointer.i"
    
    $a = ptrcreate("int",37);
    $b = ptrcreate("int",42);
    $c = ptrcreate("int");
    add($a,$b,$c);
    $r = ptrvalue($c);
    print "Result = $r\n";
    ptrfree($a);
    ptrfree($b);
    ptrfree($c);
    
    The advantage to using the pointer library is that it unifies some of the helper functions behind a common set of names. For example, the same set of functions work with int, double, float, and other fundamental types.

  • Use the SWIG typemap library. This library allows you to completely change the way arguments are processed by SWIG. For example:
    %include "typemaps.i"
    void add(int *INPUT, int *INPUT, int *OUTPUT);
    
    And in a script:
    $r = add(37,42);
    print "Result = $r\n";
    
    Needless to say, this is substantially easier.

  • A final alternative is to use the typemaps library in combination with the %apply directive. This allows you to change the names of parameters that behave as input or output parameters. For example:
    %include "typemaps.i"
    %apply int *INPUT {int *x, int *y};
    %apply int *OUTPUT {int *r};
    
    void add(int *x, int *y, int *r);
    void sub(int *x, int *y, int *r);
    void mul(int *x, int *y, int *r);
    ... etc ...
    

Example

The following example illustrates the use of these features for pointer extraction.

Notes

  • Since pointers are used for so many different things (arrays, output values, etc...) the complexity of pointer handling can be as complicated as you want to make it.

  • More documentation on the typemaps.i and pointer.i library files can be found in the SWIG user manual. The files also contain documentation.

  • The pointer.i library is designed primarily for convenience. If you are concerned about performance, you probably want to use a different approach.