`SWIG/Examples/tcl/pointer/`

## Simple Pointer Handling

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:

  >     set a [new_int 37]
  >     set b [new_int 42]
  >     set c [new_int 0]
  >     add $a $b $c
  >     set r [get_int $c]
  >     puts "Result = $r"
  >     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"

  > </blockquote? and in a script you would do this: <blockquote>

  >     set a [ptrcreate int 37]
  >     set b [ptrcreate int 42]
  >     set c [ptrcreate int]
  >     add $a $b $c
  >     set r [ptrvalue $c]
  >     puts "Result = $r"
  >     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:

  >     set r [add 37 42]
  >     puts "Result = $r"

  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.

- example.c (C Source)
- example.i (Swig interface)
- runme.tcl (Tcl Script)

## 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.