`SWIG/Examples/tcl/value/`

## Passing and Returning Structures by Value

`$Header: /cvsroot/swig/SWIG/Examples/tcl/value/index.html,v 1.2 2004/01/20 21:22:56 cheetah Exp $`

Occasionally, a C program will manipulate structures by value such as shown in the following code:

>     /* File : example.c */

>     typedef struct Vector {
>        double x, y, z;
>     } Vector;

>     double dot_product(Vector a, Vector b) {
>       return (a.x*b.x + a.y*b.y + a.z*b.z);
>     }

>     Vector vector_add(Vector a, Vector b) {
>       Vector r;
>       r.x = a.x + b.x;
>       r.y = a.y + b.y;
>       r.z = a.z + b.z;
>       return r;
>     }

Since SWIG only knows how to manage pointers to structures (not their internal representation), the following translations are made when wrappers are created:

>     double wrap_dot_product(Vector *a, Vector *b) {
>         return dot_product(*a,*b);
>     }

>     Vector *wrap_vector_add(Vector *a, Vector *b) {
>         Vector *r = (Vector *) malloc(sizeof(Vector));
>         *r = vector_add(*a,*b);
>         return r;
>     }

The functions are then called using pointers from the scripting language interface. It should also be noted that any function that returns a structure by value results in an implicit memory allocation. This will be a memory leak unless you take steps to free the result (see below).

## The SWIG interface

Click here to see a SWIG interface file that wraps these two functions. In this file, there are a few essential features:

- A wrapper for the `free()` function is created so that we can clean up the return result created by `vector_add()` function.

- The %inline directive is used to create a few helper functions for creating new Vector objects and to print out the value (for debugging purposes).

## A Tcl Script

Click here to see a script that uses these functions from Tcl.

## Notes

- When the '`-c++`' option is used, the resulting wrapper code for the return value changes to the following:

  >     Vector *wrap_vector_add(Vector *a, Vector *b) {
  >         Vector *r = new Vector(vector_add(*a,*b));
  >         return r;
  >     }

  Similarly, it would be a mistake to use the `free()` function from C++. A safer approach would be to write a helper function like this:

  >     %inline %{
  >        void delete_Vector(Vector *v) {
  >            delete v;
  >        }
  >     %}

- Passing parameters by value like this really isn't the best C programming style. If possible, you might change your application to use pointers.

- Similar translations are made when C++ references are used.