mirror of https://github.com/swig/swig
117 lines
2.6 KiB
HTML
117 lines
2.6 KiB
HTML
<html>
|
|
<head>
|
|
<title>SWIG:Examples:ruby:value</title>
|
|
</head>
|
|
|
|
<body bgcolor="#ffffff">
|
|
|
|
|
|
<tt>SWIG/Examples/ruby/value/</tt>
|
|
<hr>
|
|
|
|
<H2>Passing and Returning Structures by Value</H2>
|
|
|
|
<tt>$Header$</tt><br>
|
|
|
|
<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 Ruby Script</h2>
|
|
|
|
Click <a href="runme.rb">here</a> to see a script that uses these functions from Ruby.
|
|
|
|
<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>
|
|
|
|
<p>
|
|
<li>If you define C structure (or C++ class with '<tt>-c++</tt>' option)
|
|
in the interface file, the SWIG generated wrappers can automaticallyclean
|
|
up the result of return-by-reference by GC.
|
|
|
|
<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>
|