diff --git a/Examples/tcl/index.html b/Examples/tcl/index.html index 4c19356ad..165a89226 100644 --- a/Examples/tcl/index.html +++ b/Examples/tcl/index.html @@ -16,6 +16,8 @@ The following examples illustrate the use of SWIG with Tcl. 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. +

    Compilation Issues

    diff --git a/Examples/tcl/simple/example.i b/Examples/tcl/simple/example.i index 6702abb1e..c16994fea 100644 --- a/Examples/tcl/simple/example.i +++ b/Examples/tcl/simple/example.i @@ -3,3 +3,5 @@ extern int gcd(int x, int y); extern double Foo; + + diff --git a/Examples/tcl/variables/example.c b/Examples/tcl/variables/example.c index 75ffa1978..37e9feb33 100644 --- a/Examples/tcl/variables/example.c +++ b/Examples/tcl/variables/example.c @@ -4,6 +4,7 @@ #include #include +#include "example.h" int ivar = 0; short svar = 0; @@ -17,8 +18,15 @@ char cvar = 0; float fvar = 0; double dvar = 0; char *strvar = 0; +const char *cstrvar = 0; int *iptrvar = 0; char name[256] = "Dave"; +char path[256] = "/home/beazley"; + + +/* Global variables involving a structure */ +Point *ptptr = 0; +Point pt = { 10, 20 }; /* A variable that we will make read-only in the interface */ int status = 1; @@ -38,8 +46,11 @@ void print_vars() { printf("dvar = %g\n", dvar); printf("cvar = %c\n", cvar); printf("strvar = %s\n", strvar ? strvar : "(null)"); + printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)"); printf("iptrvar = %x\n", iptrvar); printf("name = %s\n", name); + printf("ptptr = %x (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0); + printf("pt = (%d, %d)\n", pt.x, pt.y); printf("status = %d\n", status); } @@ -51,4 +62,25 @@ int *new_int(int value) { return ip; } +/* A function to create a point */ +Point *new_Point(int x, int y) { + Point *p = (Point *) malloc(sizeof(Point)); + p->x = x; + p->y = y; + return p; +} + +char * Point_print(Point *p) { + static char buffer[256]; + if (p) { + sprintf(buffer,"(%d,%d)", p->x,p->y); + } else { + sprintf(buffer,"null"); + } + return buffer; +} + +void pt_print() { + printf("(%d, %d)\n", pt.x, pt.y); +} diff --git a/Examples/tcl/variables/example.h b/Examples/tcl/variables/example.h new file mode 100644 index 000000000..0f7e89594 --- /dev/null +++ b/Examples/tcl/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/Examples/tcl/variables/example.i b/Examples/tcl/variables/example.i index cbb72e4de..d62f973da 100644 --- a/Examples/tcl/variables/example.i +++ b/Examples/tcl/variables/example.i @@ -1,5 +1,8 @@ /* File : example.i */ %module example +%{ +#include "example.h" +%} /* Some global variable declarations */ extern int ivar; @@ -14,18 +17,28 @@ extern char cvar; extern float fvar; extern double dvar; extern char *strvar; +extern const char *cstrvar; extern int *iptrvar; extern char name[256]; +extern Point *ptptr; +extern Point pt; + + +/* Some read-only variables */ + +%readonly +extern int status; +extern char path[256]; +%readwrite + /* Some helper functions to make it easier to test */ extern void print_vars(); extern int *new_int(int value); - -/* A read-only variable */ - -%readonly -extern int status; -%readwrite +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); + diff --git a/Examples/tcl/variables/example.tcl b/Examples/tcl/variables/example.tcl index a2662abf9..beca1d10e 100644 --- a/Examples/tcl/variables/example.tcl +++ b/Examples/tcl/variables/example.tcl @@ -17,7 +17,10 @@ set cvar "S" set fvar 3.14159 set dvar 2.1828 set strvar "Hello World" +set cstrvar "Goodbye" set iptrvar [new_int 37] +set ptptr [new_Point 37 42] +set name "Bill" # Now print out the values of the variables @@ -35,8 +38,11 @@ puts "fvar = $fvar" puts "dvar = $dvar" puts "cvar = $cvar" puts "strvar = $strvar" +puts "cstrvar = $cstrvar" puts "iptrvar = $iptrvar" puts "name = $name" +puts "ptptr = $ptptr [Point_print $ptptr]" +puts "pt = $pt [Point_print $pt]" puts "\nVariables (values printed from C)" @@ -44,9 +50,9 @@ print_vars puts "\nNow I'm going to try and modify some read only variables"; -puts " Tring to set 'name'"; +puts " Tring to set 'path'"; if { [catch { - set name "Whoa!" + set path "Whoa!" puts "Hey, what's going on?!?! This shouldn't work" }]} { puts "Good." @@ -60,4 +66,13 @@ if { [catch { puts "Good." } +puts "\nI'm going to try and update a structure variable.\n" + +set pt $ptptr + +puts "The new value is" +pt_print +puts "You should see the value [Point_print $ptptr]" + + diff --git a/Examples/tcl/variables/index.html b/Examples/tcl/variables/index.html index adfe27fc6..368332b14 100644 --- a/Examples/tcl/variables/index.html +++ b/Examples/tcl/variables/index.html @@ -39,20 +39,10 @@ string. However, whenever the value of such a variable is set from Tcl, the ol value is destroyed using free() or delete (the choice of which depends on whether or not SWIG was run with the -c++ option).
  • signed char and unsigned char are handled as small 8-bit integers. -
  • Array variables such as 'char name[256]' are read-only variables because -SWIG doesn't really know how to change the "value" of an array. You can work -around this by writing some kind of helper function in the SWIG interface. -For example: - -
    -
    -%inline %{
    -void set_name(char *newname) {
    -    strncpy(name,newname,256);
    -}
    -%}
    -
    -
    +
  • String array variables such as 'char name[256]' are managed as Tcl strings, but +when setting the value, the result is truncated to the maximum length of the array. Furthermore, the string is assumed to be null-terminated. +
  • When structures and classes are used as global variables, they are mapped into pointers. +Getting the "value" returns a pointer to the global variable. Setting the value of a structure results in a memory copy from a pointer to the global.

    Creating read-only variables