diff options
Diffstat (limited to 'Examples/tcl/value/index.html')
| -rw-r--r-- | Examples/tcl/value/index.html | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/Examples/tcl/value/index.html b/Examples/tcl/value/index.html new file mode 100644 index 0000000..17a991e --- /dev/null +++ b/Examples/tcl/value/index.html @@ -0,0 +1,122 @@ +<html> +<head> +<title>SWIG:Examples:tcl:value</title> +</head> + +<body bgcolor="#ffffff"> + + +<tt>SWIG/Examples/tcl/value/</tt> +<hr> + +<H2>Passing and Returning Structures by Value</H2> + +<p> +Occasionally, a C program will manipulate structures by value such as shown in the +following code: + +<blockquote> +<pre> +/* 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; +} +</pre> +</blockquote> + +Since SWIG only knows how to manage pointers to structures (not their internal +representation), the following translations are made when wrappers are +created: + +<blockquote> +<pre> +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; +} +</pre> +</blockquote> + +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). + +<h2>The SWIG interface</h2> + +Click <a href="example.i">here</a> to see a SWIG interface file that +wraps these two functions. In this file, there are a few essential features: + +<ul> +<li>A wrapper for the <tt>free()</tt> function is created so that we +can clean up the return result created by <tt>vector_add()</tt> +function. + +<p> +<li>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). +</ul> + +<h2>A Tcl Script</h2> + +Click <a href="runme.tcl">here</a> to see a script that uses these functions from Tcl. + +<h2>Notes</h2> + +<ul> +<li>When the '<tt>-c++</tt>' option is used, the resulting wrapper code for the return value +changes to the following: + +<blockquote> +<pre> +Vector *wrap_vector_add(Vector *a, Vector *b) { + Vector *r = new Vector(vector_add(*a,*b)); + return r; +} +</pre> +</blockquote> + +Similarly, it would be a mistake to use the <tt>free()</tt> function from C++. A safer +approach would be to write a helper function like this: + +<blockquote> +<pre> +%inline %{ + void delete_Vector(Vector *v) { + delete v; + } +%} +</pre> +</blockquote> + +<p> +<li>Passing parameters by value like this really isn't the best C programming style. +If possible, you might change your application to use pointers. + +<p> +<li>Similar translations are made when C++ references are used. + + +</ul> + +<hr> +</body> +</html> |
