SWIG/Examples/ruby/value/
Passing and Returning Structures by Value
$Header: /cvsroot/swig/SWIG/Examples/ruby/value/index.html,v 1.1 2000/09/18 13:21:27 fukusima 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 Ruby Script
Click here to see a script that uses these functions from Ruby.
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;
}
- If you define C structure (or C++ class with '-c++' option)
in the interface file, the SWIG generated wrappers can automaticallyclean
up the result of return-by-reference by GC.
- 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.