diff --git a/Examples/tcl/index.html b/Examples/tcl/index.html
index 165a89226..cc24e3192 100644
--- a/Examples/tcl/index.html
+++ b/Examples/tcl/index.html
@@ -17,7 +17,7 @@ be used to wrap a C function and a global variable.
constants. This shows how preprocessor macros and
certain C declarations are turned into constants.
variables. How SWIG can be used to wrap C global variables.
-
+value. How to pass and return structures by value.
Compilation Issues
diff --git a/Examples/tcl/simple/example.tcl b/Examples/tcl/simple/example.tcl
index af3b29510..10a581099 100644
--- a/Examples/tcl/simple/example.tcl
+++ b/Examples/tcl/simple/example.tcl
@@ -1,5 +1,5 @@
# file: example.tcl
-# Try to load as a dynamic module. If not, we'll just assume
+# Try to load as a dynamic module.
catch { load ./example.so example}
catch { load ./example.dll example} ;# Windows
diff --git a/Examples/tcl/value/Makefile b/Examples/tcl/value/Makefile
new file mode 100644
index 000000000..fcb994d09
--- /dev/null
+++ b/Examples/tcl/value/Makefile
@@ -0,0 +1,19 @@
+TOP = ../..
+SWIG = $(TOP)/../swig
+SRCS = example.c
+TARGET = my_tclsh
+DLTARGET = example
+INTERFACE = example.i
+
+all::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ TARGET='$(DLTARGET)' INTERFACE='$(INTERFACE)' tcl
+
+static::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' tclsh
+
+clean::
+ rm -f *_wrap* *.o my_tclsh *~ .~* core *.so *.sl
+
+check: all
diff --git a/Examples/tcl/value/example.c b/Examples/tcl/value/example.c
new file mode 100644
index 000000000..4ed2fe10a
--- /dev/null
+++ b/Examples/tcl/value/example.c
@@ -0,0 +1,15 @@
+/* File : example.c */
+
+#include "example.h"
+
+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;
+}
diff --git a/Examples/tcl/value/example.h b/Examples/tcl/value/example.h
new file mode 100644
index 000000000..212cf4bdb
--- /dev/null
+++ b/Examples/tcl/value/example.h
@@ -0,0 +1,5 @@
+/* File : example.h */
+
+typedef struct {
+ double x, y, z;
+} Vector;
diff --git a/Examples/tcl/value/example.i b/Examples/tcl/value/example.i
new file mode 100644
index 000000000..83c1f9cd6
--- /dev/null
+++ b/Examples/tcl/value/example.i
@@ -0,0 +1,30 @@
+// Tests SWIG's handling of pass-by-value for complex datatypes
+%module example
+
+%{
+#include "example.h"
+%}
+
+/* Some functions that manipulate Vectors by value */
+extern double dot_product(Vector a, Vector b);
+extern Vector vector_add(Vector a, Vector b);
+
+/* Include this because the vector_add() function will leak memory */
+void free(void *);
+
+/* Some helper functions for our interface */
+%inline %{
+
+Vector *new_Vector(double x, double y, double z) {
+ Vector *v = (Vector *) malloc(sizeof(Vector));
+ v->x = x;
+ v->y = y;
+ v->z = z;
+ return v;
+}
+
+void vector_print(Vector *v) {
+ printf("Vector %x = (%g, %g, %g)\n", v, v->x, v->y, v->z);
+}
+%}
+
diff --git a/Examples/tcl/value/example.tcl b/Examples/tcl/value/example.tcl
new file mode 100644
index 000000000..a4291f9cb
--- /dev/null
+++ b/Examples/tcl/value/example.tcl
@@ -0,0 +1,40 @@
+# file: example.py
+# Try to load as a dynamic module.
+
+catch { load ./example.so example}
+catch { load ./example.dll example} ;# Windows
+
+# Create a couple of a vectors
+
+set v [new_Vector 1 2 3]
+set w [new_Vector 10 11 12]
+
+puts "I just created the following vectors"
+vector_print $v
+vector_print $w
+
+# Now call some of our functions
+
+puts "\nNow I'm going to compute the dot product"
+set d [dot_product $v $w]
+puts "dot product = $d (should be 68)"
+
+# Add the vectors together
+
+puts "\nNow I'm going to add the vectors together"
+set r [vector_add $v $w]
+vector_print $r
+puts "The value should be (11,13,15)"
+
+# Now I'd better clean up the return result r
+
+puts "\nNow I'm going to clean up the return result"
+free $r
+
+puts "Good"
+
+
+
+
+
+
diff --git a/Examples/tcl/value/index.html b/Examples/tcl/value/index.html
new file mode 100644
index 000000000..02b79e7ba
--- /dev/null
+++ b/Examples/tcl/value/index.html
@@ -0,0 +1,124 @@
+
+
+SWIG:Examples:tcl:value
+
+
+
+
+
+SWIG/Examples/tcl/value/
+
+
+Passing and Returning Structures by Value
+
+$Header$
+
+
+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 Tcl Script
+
+Click here to see a script that uses these functions from Tcl.
+
+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;
+}
+
+
+
+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;
+ }
+%}
+
+
+
+
+
- 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.
+
+
+
+
+
+
+