summaryrefslogtreecommitdiff
path: root/Examples/perl5/value/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'Examples/perl5/value/index.html')
-rw-r--r--Examples/perl5/value/index.html126
1 files changed, 126 insertions, 0 deletions
diff --git a/Examples/perl5/value/index.html b/Examples/perl5/value/index.html
new file mode 100644
index 0000000..62c1a03
--- /dev/null
+++ b/Examples/perl5/value/index.html
@@ -0,0 +1,126 @@
+<html>
+<head>
+<title>SWIG:Examples:perl5:value</title>
+</head>
+
+<body bgcolor="#ffffff">
+
+
+<tt>SWIG/Examples/perl5/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 Perl Script</h2>
+
+Click <a href="runme.pl">here</a> to see a script that uses these functions from Perl.
+
+<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>If you use proxy 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.
+
+<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>