From 3621fe789f06c723255723664c8a3078d1fc6d1c Mon Sep 17 00:00:00 2001 From: Dave Beazley Date: Wed, 30 Aug 2000 22:38:51 +0000 Subject: New example git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@742 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/python/index.html | 1 + Examples/python/variables/Makefile | 18 +++++++ Examples/python/variables/example.c | 86 +++++++++++++++++++++++++++++ Examples/python/variables/example.h | 6 +++ Examples/python/variables/example.i | 44 +++++++++++++++ Examples/python/variables/example.py | 76 ++++++++++++++++++++++++++ Examples/python/variables/index.html | 102 +++++++++++++++++++++++++++++++++++ 7 files changed, 333 insertions(+) create mode 100644 Examples/python/variables/Makefile create mode 100644 Examples/python/variables/example.c create mode 100644 Examples/python/variables/example.h create mode 100644 Examples/python/variables/example.i create mode 100644 Examples/python/variables/example.py create mode 100644 Examples/python/variables/index.html (limited to 'Examples/python') diff --git a/Examples/python/index.html b/Examples/python/index.html index a36cb8c2e..f80417bd2 100644 --- a/Examples/python/index.html +++ b/Examples/python/index.html @@ -16,6 +16,7 @@ The following examples illustrate the use of SWIG with Python. be used to wrap a C function, a global variable, and a constant.
  • constants. This shows how preprocessor macros and certain C declarations are turned into constants. +
  • variables. An example showing how to access C global variables from Python.

    Compilation Issues

    diff --git a/Examples/python/variables/Makefile b/Examples/python/variables/Makefile new file mode 100644 index 000000000..e495cfa9a --- /dev/null +++ b/Examples/python/variables/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../swig +SRCS = example.c +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_static + +clean:: + rm -f *_wrap* *.o *~ *.so mypython *.pyc .~* core + +check: all diff --git a/Examples/python/variables/example.c b/Examples/python/variables/example.c new file mode 100644 index 000000000..37e9feb33 --- /dev/null +++ b/Examples/python/variables/example.c @@ -0,0 +1,86 @@ +/* File : example.c */ + +/* I'm a file containing some C global variables */ + +#include +#include +#include "example.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; +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; + +/* 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("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); +} + +/* A function to create an integer (to test iptrvar) */ + +int *new_int(int value) { + int *ip = (int *) malloc(sizeof(int)); + *ip = 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/python/variables/example.h b/Examples/python/variables/example.h new file mode 100644 index 000000000..0f7e89594 --- /dev/null +++ b/Examples/python/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/Examples/python/variables/example.i b/Examples/python/variables/example.i new file mode 100644 index 000000000..d62f973da --- /dev/null +++ b/Examples/python/variables/example.i @@ -0,0 +1,44 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* 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 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); +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); + + + + diff --git a/Examples/python/variables/example.py b/Examples/python/variables/example.py new file mode 100644 index 000000000..7aab7a38f --- /dev/null +++ b/Examples/python/variables/example.py @@ -0,0 +1,76 @@ +# file: example.py + +import example + +# Try to set the values of some global variables + +example.cvar.ivar = 42 +example.cvar.svar = -31000 +example.cvar.lvar = 65537 +example.cvar.uivar = 123456 +example.cvar.usvar = 61000 +example.cvar.ulvar = 654321 +example.cvar.scvar = -13 +example.cvar.ucvar = 251 +example.cvar.cvar = "S" +example.cvar.fvar = 3.14159 +example.cvar.dvar = 2.1828 +example.cvar.strvar = "Hello World" +example.cvar.cstrvar = "Goodbye" +example.cvar.iptrvar= example.new_int(37) +example.cvar.ptptr = example.new_Point(37,42) +example.cvar.name = "Bill" + +# Now print out the values of the variables + +print "Variables (values printed from Python)" + +print "ivar =", example.cvar.ivar +print "svar =", example.cvar.svar +print "lvar =", example.cvar.lvar +print "uivar =", example.cvar.uivar +print "usvar =", example.cvar.usvar +print "ulvar =", example.cvar.ulvar +print "scvar =", example.cvar.scvar +print "ucvar =", example.cvar.ucvar +print "fvar =", example.cvar.fvar +print "dvar =", example.cvar.dvar +print "cvar =", example.cvar.cvar +print "strvar =", example.cvar.strvar +print "cstrvar =", example.cvar.cstrvar +print "iptrvar =", example.cvar.iptrvar +print "name =", example.cvar.name +print "ptptr =", example.cvar.ptptr, example.Point_print(example.cvar.ptptr) +print "pt =", example.cvar.pt, example.Point_print(example.cvar.pt) + +print "\nVariables (values printed from C)" + +example.print_vars() + +print "\nNow I'm going to try and modify some read only variables"; + +print " Tring to set 'path'"; +try: + example.cvar.path = "Whoa!" + print "Hey, what's going on?!?! This shouldn't work" +except: + print "Good." + +print " Trying to set 'status'"; +try: + example.cvar.status = 0 + print "Hey, what's going on?!?! This shouldn't work" +except: + print "Good." + + +print "\nI'm going to try and update a structure variable.\n" + +example.cvar.pt = example.cvar.ptptr + +print "The new value is" +example.pt_print() +print "You should see the value", example.Point_print(example.cvar.ptptr) + + + diff --git a/Examples/python/variables/index.html b/Examples/python/variables/index.html new file mode 100644 index 000000000..12cacbf64 --- /dev/null +++ b/Examples/python/variables/index.html @@ -0,0 +1,102 @@ + + +SWIG:Examples:python:variables + + + + +SWIG/Examples/python/variables/ +
    + +

    Wrapping C Global Variables

    + +$Header$
    + +

    +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 Python variable that magically +retrieves or updates the value of the underlying C variable when it is +accessed. Click here to see a SWIG interface with some variable +declarations in it. + +

    Manipulating Variables from Python

    + +Before going any further, it is important to understand some important +differences between C and Python variables. In C, a variable is +simply a name that refers to a specific location in memory. For +example, when you declare a global variable 'double a' you +know that somewhere in memory, 8 bytes have been set aside to hold a +double and that a is bound to this location for the +life of the program. In Python, variable creation is nothing more +than a naming operation. For example, when you say 'a = 3', +'a' becomes a name that refers to some object '3'. Later on, if you say +'a = 7.5, the name 'a' is bound to an entirely different object +containing the value '7.5' (the contents of the original object are not +changed). The end result of this is that a variable in Python can refer +to a virtually unlimited number of different objects (memory locations) +over the lifetime of a program. + +

    +Because of Python's somewhat unusual variable assignment semantics, it is not +possible to directly link a C global variable into an equivalent Python variable. +Instead, all C global variables are accessed as attributes of a special object +called 'cvar'. For example, if you had a global variable + +

    +
    +double foo;
    +
    +
    + +it will be accessed in the Python module as cvar.foo. Click +here to see a script that updates and prints +out the values of the variables using this technique. + +

    Key points

    + +
      +
    • When a global variable has the type "char *", SWIG manages it as a character +string. However, whenever the value of such a variable is set from Python, the old +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. +
    • String array variables such as 'char name[256]' are managed as Python 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

    + +The %readonly and %readwrite directives can be used to +specify a collection of read-only variables. For example: + +
    +
    +%readonly
    +int    status;
    +double blah;
    +...
    +%readwrite
    +
    +
    + +The %readonly directive remains in effect until it is explicitly disabled +using the %readwrite directive. + +

    Comments

    +
      +
    • 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. +

      +

    • Because of the potential for a namespace conflict, you should not use +the from module import * statement for a SWIG module with global +variables. Doing so will cause a collision on the 'cvar' object should +more than one module be loaded in this manner. +
    + + + +
    \ No newline at end of file -- cgit v1.2.3