New example

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@727 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dave Beazley 2000-08-30 16:26:58 +00:00
commit 12999f703a
5 changed files with 255 additions and 0 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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."
}

View file

@ -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>