summaryrefslogtreecommitdiff
path: root/Examples/tcl/variables
diff options
context:
space:
mode:
authorDave Beazley <dave-swig@dabeaz.com>2000-08-30 16:26:58 +0000
committerDave Beazley <dave-swig@dabeaz.com>2000-08-30 16:26:58 +0000
commit12999f703a79e7f0ed8f5a1180b035dbeeb4c32f (patch)
tree6ba55eb0ecd113d6193fdc2fabc4b5fd02ec9b96 /Examples/tcl/variables
parent887d79cae3bf470a6bbfb73fdbb254d54b26ca3c (diff)
downloadswig-12999f703a79e7f0ed8f5a1180b035dbeeb4c32f.tar.gz
New example
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@727 626c5289-ae23-0410-ae9c-e8d60b6d4f22
Diffstat (limited to 'Examples/tcl/variables')
-rw-r--r--Examples/tcl/variables/Makefile19
-rw-r--r--Examples/tcl/variables/example.c54
-rw-r--r--Examples/tcl/variables/example.i31
-rw-r--r--Examples/tcl/variables/example.tcl63
-rw-r--r--Examples/tcl/variables/index.html88
5 files changed, 255 insertions, 0 deletions
diff --git a/Examples/tcl/variables/Makefile b/Examples/tcl/variables/Makefile
new file mode 100644
index 000000000..fcb994d09
--- /dev/null
+++ b/Examples/tcl/variables/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/variables/example.c b/Examples/tcl/variables/example.c
new file mode 100644
index 000000000..75ffa1978
--- /dev/null
+++ b/Examples/tcl/variables/example.c
@@ -0,0 +1,54 @@
+/* File : example.c */
+
+/* I'm a file containing some C global variables */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int ivar = 0;
+short svar = 0;
+long lvar = 0;
+unsigned int uivar = 0;
+unsigned short usvar = 0;
+unsigned long ulvar = 0;
+signed char scvar = 0;
+unsigned char ucvar = 0;
+char cvar = 0;
+float fvar = 0;
+double dvar = 0;
+char *strvar = 0;
+int *iptrvar = 0;
+char name[256] = "Dave";
+
+/* A variable that we will make read-only in the interface */
+int status = 1;
+
+/* A debugging function to print out their values */
+
+void print_vars() {
+ printf("ivar = %d\n", ivar);
+ printf("svar = %d\n", svar);
+ printf("lvar = %ld\n", lvar);
+ printf("uivar = %u\n", uivar);
+ printf("usvar = %u\n", usvar);
+ printf("ulvar = %lu\n", ulvar);
+ printf("scvar = %d\n", scvar);
+ printf("ucvar = %u\n", ucvar);
+ printf("fvar = %g\n", fvar);
+ printf("dvar = %g\n", dvar);
+ printf("cvar = %c\n", cvar);
+ printf("strvar = %s\n", strvar ? strvar : "(null)");
+ printf("iptrvar = %x\n", iptrvar);
+ printf("name = %s\n", name);
+ printf("status = %d\n", status);
+}
+
+/* A function to create an integer (to test iptrvar) */
+
+int *new_int(int value) {
+ int *ip = (int *) malloc(sizeof(int));
+ *ip = value;
+ return ip;
+}
+
+
diff --git a/Examples/tcl/variables/example.i b/Examples/tcl/variables/example.i
new file mode 100644
index 000000000..cbb72e4de
--- /dev/null
+++ b/Examples/tcl/variables/example.i
@@ -0,0 +1,31 @@
+/* File : example.i */
+%module example
+
+/* Some global variable declarations */
+extern int ivar;
+extern short svar;
+extern long lvar;
+extern unsigned int uivar;
+extern unsigned short usvar;
+extern unsigned long ulvar;
+extern signed char scvar;
+extern unsigned char ucvar;
+extern char cvar;
+extern float fvar;
+extern double dvar;
+extern char *strvar;
+extern int *iptrvar;
+extern char name[256];
+
+/* 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
+
+
+
diff --git a/Examples/tcl/variables/example.tcl b/Examples/tcl/variables/example.tcl
new file mode 100644
index 000000000..a2662abf9
--- /dev/null
+++ b/Examples/tcl/variables/example.tcl
@@ -0,0 +1,63 @@
+# file: example.tcl
+
+catch { load ./example.so example} ;# Unix
+catch { load ./example.dll example} ;# Windows
+
+# Try to set the values of some global variables
+
+set ivar 42
+set svar -31000
+set lvar 65537
+set uivar 123456
+set usvar 61000
+set ulvar 654321
+set scvar -13
+set ucvar 251
+set cvar "S"
+set fvar 3.14159
+set dvar 2.1828
+set strvar "Hello World"
+set iptrvar [new_int 37]
+
+# Now print out the values of the variables
+
+puts "Variables (values printed from Tcl)"
+
+puts "ivar = $ivar"
+puts "svar = $svar"
+puts "lvar = $lvar"
+puts "uivar = $uivar"
+puts "usvar = $usvar"
+puts "ulvar = $ulvar"
+puts "scvar = $scvar"
+puts "ucvar = $ucvar"
+puts "fvar = $fvar"
+puts "dvar = $dvar"
+puts "cvar = $cvar"
+puts "strvar = $strvar"
+puts "iptrvar = $iptrvar"
+puts "name = $name"
+
+puts "\nVariables (values printed from C)"
+
+print_vars
+
+puts "\nNow I'm going to try and modify some read only variables";
+
+puts " Tring to set 'name'";
+if { [catch {
+ set name "Whoa!"
+ puts "Hey, what's going on?!?! This shouldn't work"
+}]} {
+ puts "Good."
+}
+
+puts " Trying to set 'status'";
+if { [catch {
+ set status 0
+ puts "Hey, what's going on?!?! This shouldn't work"
+}]} {
+ puts "Good."
+}
+
+
diff --git a/Examples/tcl/variables/index.html b/Examples/tcl/variables/index.html
new file mode 100644
index 000000000..adfe27fc6
--- /dev/null
+++ b/Examples/tcl/variables/index.html
@@ -0,0 +1,88 @@
+<html>
+<head>
+<title>SWIG:Examples:tcl:variables</title>
+</head>
+
+<body bgcolor="#ffffff">
+
+<tt>SWIG/Examples/tcl/variables/</tt>
+<hr>
+
+<H2>Wrapping C Global Variables</H2>
+
+<tt>$Header$</tt><br>
+
+<p>
+When a C global variable appears in an interface file, SWIG tries to wrap it using a technique
+known as "variable linking." The idea is pretty simple---we try to create a Tcl
+variable that works exactly like you would expect in a Tcl script, but which magically
+retrieves or updates the value of the underlying C variable.
+Click <a href="example.i">here</a> to see a SWIG interface with some variable declarations in it.
+
+<h2>Manipulating Variables from Tcl</h2>
+
+Click <a href="example.tcl">here</a> to see a script that updates and prints out the values of
+the variables defined in the above file. Notice how the C global variables work just
+like normal Tcl variables.
+
+<h2>Key points</h2>
+
+<ul>
+<li>The <tt>set</tt> statement changes the value of the corresponding C global variable.
+<li>Whenever you access the value of a variable such as <tt>$ivar</tt>, the value
+of the C global variable is read.
+<li>If a C program changes a global variable independently of Tcl, this change is
+automatically reflected in the Tcl variable (i.e., reads will always return the
+most up to date value of the variable).
+<li>When a global variable has the type "<tt>char *</tt>", SWIG manages it as a character
+string. However, whenever the value of such a variable is set from Tcl, the old
+value is destroyed using <tt>free()</tt> or <tt>delete</tt> (the choice of which depends
+on whether or not SWIG was run with the -c++ option).
+<li><tt>signed char</tt> and <tt>unsigned char</tt> are handled as small 8-bit integers.
+<li>Array variables such as '<tt>char name[256]</tt>' 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:
+
+<blockquote>
+<pre>
+%inline %{
+void set_name(char *newname) {
+ strncpy(name,newname,256);
+}
+%}
+</pre>
+</blockquote>
+</ul>
+
+<h2>Creating read-only variables</h2>
+
+The <tt>%readonly</tt> and <tt>%readwrite</tt> directives can be used to
+specify a collection of read-only variables. For example:
+
+<blockquote>
+<pre>
+%readonly
+int status;
+double blah;
+...
+%readwrite
+</pre>
+</blockquote>
+
+The <tt>%readonly</tt> directive remains in effect until it is explicitly disabled
+using the <tt>%readwrite</tt> directive.
+
+<h2>Comments</h2>
+<ul>
+<li>Management of global variables is one of the most problematic aspects
+of C/C++ wrapping because the scripting interface and resulting memory management
+is much trickier than simply creating a wrapper function.
+<p>
+<li>You may be better off hiding global variables behind a function based
+interface.
+</ul>
+
+</body>
+</html>
+<hr> \ No newline at end of file