From 794ff1ed6c0493cbe03f198f75d5c49489cbc2fb Mon Sep 17 00:00:00 2001 From: Dave Beazley Date: Thu, 31 Aug 2000 18:07:07 +0000 Subject: [PATCH] New example git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@762 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/tcl/index.html | 2 +- Examples/tcl/simple/example.tcl | 2 +- Examples/tcl/value/Makefile | 19 +++++ Examples/tcl/value/example.c | 15 ++++ Examples/tcl/value/example.h | 5 ++ Examples/tcl/value/example.i | 30 ++++++++ Examples/tcl/value/example.tcl | 40 +++++++++++ Examples/tcl/value/index.html | 124 ++++++++++++++++++++++++++++++++ 8 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 Examples/tcl/value/Makefile create mode 100644 Examples/tcl/value/example.c create mode 100644 Examples/tcl/value/example.h create mode 100644 Examples/tcl/value/example.i create mode 100644 Examples/tcl/value/example.tcl create mode 100644 Examples/tcl/value/index.html 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 Tcl Script

    + +Click here to see a script that uses these functions from Tcl. + +

    Notes

    + + + +
    + +