  GNU-Darwin Web
SWIG/Examples/python/value/

## Passing and Returning Structures by Value

\$Header: /cvs/projects/SWIG/Examples/python/value/index.html,v 1.1 2000/08/31 17:12:41 beazley 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));
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 Python Script

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

## 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) {
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;
}
%}
```

• If you use shadow classes and are careful, the SWIG generated wrappers can automatically clean up the result of return-by-reference when the scripting variable goes out of scope.

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