diff options
Diffstat (limited to 'trunk/Examples/python')
154 files changed, 6326 insertions, 0 deletions
diff --git a/trunk/Examples/python/callback/Makefile b/trunk/Examples/python/callback/Makefile new file mode 100644 index 000000000..a29276e58 --- /dev/null +++ b/trunk/Examples/python/callback/Makefile @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/callback/example.cxx b/trunk/Examples/python/callback/example.cxx new file mode 100644 index 000000000..450d75608 --- /dev/null +++ b/trunk/Examples/python/callback/example.cxx @@ -0,0 +1,4 @@ +/* File : example.cxx */ + +#include "example.h" + diff --git a/trunk/Examples/python/callback/example.h b/trunk/Examples/python/callback/example.h new file mode 100644 index 000000000..2a0194999 --- /dev/null +++ b/trunk/Examples/python/callback/example.h @@ -0,0 +1,22 @@ +/* File : example.h */ + +#include <iostream> + +class Callback { +public: + virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; } + virtual void run() { std::cout << "Callback::run()" << std::endl; } +}; + + +class Caller { +private: + Callback *_callback; +public: + Caller(): _callback(0) {} + ~Caller() { delCallback(); } + void delCallback() { delete _callback; _callback = 0; } + void setCallback(Callback *cb) { delCallback(); _callback = cb; } + void call() { if (_callback) _callback->run(); } +}; + diff --git a/trunk/Examples/python/callback/example.i b/trunk/Examples/python/callback/example.i new file mode 100644 index 000000000..90beda01a --- /dev/null +++ b/trunk/Examples/python/callback/example.i @@ -0,0 +1,13 @@ +/* File : example.i */ +%module(directors="1") example +%{ +#include "example.h" +%} + +%include "std_string.i" + +/* turn on director wrapping Callback */ +%feature("director") Callback; + +%include "example.h" + diff --git a/trunk/Examples/python/callback/index.html b/trunk/Examples/python/callback/index.html new file mode 100644 index 000000000..e2017eca3 --- /dev/null +++ b/trunk/Examples/python/callback/index.html @@ -0,0 +1,19 @@ +<html> +<head> +<title>SWIG:Examples:python:callback</title> +</head> + +<body bgcolor="#ffffff"> + + +<tt>SWIG/Examples/python/extend/</tt> +<hr> + +<H2>Implementing C++ callbacks in Python</H2> + +<p> +This example illustrates how to use directors to implement C++ callbacks in Python. + +<hr> +</body> +</html> diff --git a/trunk/Examples/python/callback/runme.py b/trunk/Examples/python/callback/runme.py new file mode 100644 index 000000000..026e9520b --- /dev/null +++ b/trunk/Examples/python/callback/runme.py @@ -0,0 +1,56 @@ +# file: runme.py + +# This file illustrates the cross language polymorphism using directors. + +import example + + +class PyCallback(example.Callback): + def __init__(self): + example.Callback.__init__(self) + def run(self): + print "PyCallback.run()" + +# Create an Caller instance + +caller = example.Caller() + +# Add a simple C++ callback (caller owns the callback, so +# we disown it first by clearing the .thisown flag). + +print "Adding and calling a normal C++ callback" +print "----------------------------------------" + +callback = example.Callback() +callback.thisown = 0 +caller.setCallback(callback) +caller.call() +caller.delCallback(); + +print +print "Adding and calling a Python callback" +print "------------------------------------" + +# Add a Python callback (caller owns the callback, so we +# disown it first by calling __disown__). + +caller.setCallback(PyCallback().__disown__()) +caller.call() +caller.delCallback() + +print +print "Adding and calling another Python callback" +print "------------------------------------------" + +# Lets do the same but use the weak reference this time. + +callback = PyCallback().__disown__() +caller.setCallback(callback) +caller.call() +caller.delCallback() + +# All done. + +print +print "python exit" + diff --git a/trunk/Examples/python/check.list b/trunk/Examples/python/check.list new file mode 100644 index 000000000..7cfe437f0 --- /dev/null +++ b/trunk/Examples/python/check.list @@ -0,0 +1,29 @@ +# see top-level Makefile.in +callback +class +constants +contract +docstrings +enum +exception +exceptproxy +extend +funcptr +funcptr2 +functor +import +import_template +java +#libffi +multimap +operator +pointer +reference +simple +smartptr +std_vector +std_map +swigrun +template +varargs +variables diff --git a/trunk/Examples/python/class/Makefile b/trunk/Examples/python/class/Makefile new file mode 100644 index 000000000..74625b992 --- /dev/null +++ b/trunk/Examples/python/class/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/class/example.cxx b/trunk/Examples/python/class/example.cxx new file mode 100644 index 000000000..1e8e203dd --- /dev/null +++ b/trunk/Examples/python/class/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ + +#include "example.h" +#define M_PI 3.14159265358979323846 + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/trunk/Examples/python/class/example.dsp b/trunk/Examples/python/class/example.dsp new file mode 100644 index 000000000..fd7bf8c06 --- /dev/null +++ b/trunk/Examples/python/class/example.dsp @@ -0,0 +1,152 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=example - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "example.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "example - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /debug /machine:I386 /out:"_example.pyd" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "example - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /machine:I386 /out:"_example.pyd"
+
+!ENDIF
+
+# Begin Target
+
+# Name "example - Win32 Debug"
+# Name "example - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\example.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\example_wrap.cxx
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\example.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Source File
+
+SOURCE=.\example.i
+
+!IF "$(CFG)" == "example - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\example.i
+InputName=example
+
+"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -c++ -python $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "example - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\example.i
+InputName=example
+
+"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -c++ -python $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/trunk/Examples/python/class/example.h b/trunk/Examples/python/class/example.h new file mode 100644 index 000000000..46d901361 --- /dev/null +++ b/trunk/Examples/python/class/example.h @@ -0,0 +1,39 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; + + + + + diff --git a/trunk/Examples/python/class/example.i b/trunk/Examples/python/class/example.i new file mode 100644 index 000000000..75700b305 --- /dev/null +++ b/trunk/Examples/python/class/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/trunk/Examples/python/class/index.html b/trunk/Examples/python/class/index.html new file mode 100644 index 000000000..12c5eded1 --- /dev/null +++ b/trunk/Examples/python/class/index.html @@ -0,0 +1,216 @@ +<html> +<head> +<title>SWIG:Examples:python:class</title> +</head> + +<body bgcolor="#ffffff"> + + +<tt>SWIG/Examples/python/class/</tt> +<hr> + +<H2>Wrapping a simple C++ class</H2> + +<p> +This example illustrates the most primitive form of C++ class wrapping performed +by SWIG. In this case, C++ classes are simply transformed into a collection of +C-style functions that provide access to class members. + +<h2>The C++ Code</h2> + +Suppose you have some C++ classes described by the following (and admittedly lame) +header file: + +<blockquote> +<pre> +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area() = 0; + virtual double perimeter() = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(); + virtual double perimeter(); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(); + virtual double perimeter(); +}; +</pre> +</blockquote> + +<h2>The SWIG interface</h2> + +A simple SWIG interface for this can be built by simply grabbing the header file +like this: + +<blockquote> +<pre> +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" +</pre> +</blockquote> + +Note: when creating a C++ extension, you must run SWIG with the <tt>-c++</tt> option like this: +<blockquote> +<pre> +% swig -c++ -python example.i +</pre> +</blockquote> + +<h2>A sample Python script</h2> + +Click <a href="example.py">here</a> to see a script that calls the C++ functions from Python. + +<h2>Key points</h2> + +<ul> +<li>To create a new object, you call a constructor like this: + +<blockquote> +<pre> +c = example.new_Circle(10.0) +</pre> +</blockquote> + +<p> +<li>To access member data, a pair of accessor functions are used. +For example: + +<blockquote> +<pre> +example.Shape_x_set(c,15) # Set member data +x = example.Shape_x_get(c) # Get member data +</pre> +</blockquote> + +Note: when accessing member data, the name of the class in which +the member data was must be used. In this case, <tt>Shape_x_get()</tt> +and <tt>Shape_x_set()</tt> are used since 'x' was defined in Shape. + +<p> +<li>To invoke a member function, you simply do this + +<blockquote> +<pre> +print "The area is ", example.Shape_area(c) +</pre> +</blockquote> + +<p> +<li>Type checking knows about the inheritance structure of C++. For example: + +<blockquote> +<pre> +example.Shape_area(c) # Works (c is a Shape) +example.Circle_area(c) # Works (c is a Circle) +example.Square_area(c) # Fails (c is definitely not a Square) +</pre> +</blockquote> + +<p> +<li>To invoke a destructor, simply do this + +<blockquote> +<pre> +example.delete_Shape(c) # Deletes a shape +</pre> +</blockquote> + +(Note: destructors are currently not inherited. This might change later). + +<p> +<li>Static member variables are wrapped as C global variables. For example: + +<blockquote> +<pre> +n = example.cvar.Shape_nshapes # Get a static data member +example.cvar.Shapes_nshapes = 13 # Set a static data member +</pre> +</blockquote> + +</ul> + +<h2>General Comments</h2> + +<ul> +<li>This low-level interface is not the only way to handle C++ code. +Proxy classes provide a much higher-level interface. + +<p> +<li>SWIG *does* know how to properly perform upcasting of objects in +an inheritance hierarchy (including multiple inheritance). Therefore +it is perfectly safe to pass an object of a derived class to any +function involving a base class. + +<p> +<li>A wide variety of C++ features are not currently supported by SWIG. Here is the +short and incomplete list: + +<p> +<ul> +<li>Overloaded methods and functions. SWIG wrappers don't know how to resolve name +conflicts so you must give an alternative name to any overloaded method name using the +%name directive like this: + +<blockquote> +<pre> +void foo(int a); +%name(foo2) void foo(double a, double b); +</pre> +</blockquote> + +<p> +<li>Overloaded operators. Not supported at all. The only workaround for this is +to write a helper function. For example: + +<blockquote> +<pre> +%inline %{ + Vector *vector_add(Vector *a, Vector *b) { + ... whatever ... + } +%} +</pre> +</blockquote> + +<p> +<li>Namespaces. Not supported at all. Won't be supported until SWIG2.0 (if at all). + +<p> +<li>Dave's snide remark: Like a large bottle of strong Tequilla, it's better to +use C++ in moderation. + +</ul> + +<hr> +</body> +</html> diff --git a/trunk/Examples/python/class/runme.py b/trunk/Examples/python/class/runme.py new file mode 100644 index 000000000..f1272ae81 --- /dev/null +++ b/trunk/Examples/python/class/runme.py @@ -0,0 +1,51 @@ +# file: runme.py + +# This file illustrates the proxy class C++ interface generated +# by SWIG. + +import example + +# ----- Object creation ----- + +print "Creating some objects:" +c = example.Circle(10) +print " Created circle", c +s = example.Square(10) +print " Created square", s + +# ----- Access a static member ----- + +print "\nA total of", example.cvar.Shape_nshapes,"shapes were created" + +# ----- Member data access ----- + +# Set the location of the object + +c.x = 20 +c.y = 30 + +s.x = -10 +s.y = 5 + +print "\nHere is their current position:" +print " Circle = (%f, %f)" % (c.x,c.y) +print " Square = (%f, %f)" % (s.x,s.y) + +# ----- Call some methods ----- + +print "\nHere are some properties of the shapes:" +for o in [c,s]: + print " ", o + print " area = ", o.area() + print " perimeter = ", o.perimeter() + +print "\nGuess I'll clean up now" + +# Note: this invokes the virtual destructor +del c +del s + +s = 3 +print example.cvar.Shape_nshapes,"shapes remain" +print "Goodbye" + diff --git a/trunk/Examples/python/constants/Makefile b/trunk/Examples/python/constants/Makefile new file mode 100644 index 000000000..1420b4e0b --- /dev/null +++ b/trunk/Examples/python/constants/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = +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:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/constants/example.i b/trunk/Examples/python/constants/example.i new file mode 100644 index 000000000..4f7b1a4d7 --- /dev/null +++ b/trunk/Examples/python/constants/example.i @@ -0,0 +1,27 @@ +/* File : example.i */ +%module example + +/* A few preprocessor macros */ + +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" + +/* This should work just fine */ +#define EXPR ICONST + 3*(FCONST) + +/* This shouldn't do anything */ +#define EXTERN extern + +/* Neither should this (BAR isn't defined) */ +#define FOO (ICONST + BAR) + +/* The following directives also produce constants */ + +%constant int iconst = 37; +%constant double fconst = 3.14; + + diff --git a/trunk/Examples/python/constants/index.html b/trunk/Examples/python/constants/index.html new file mode 100644 index 000000000..35cc0d7e6 --- /dev/null +++ b/trunk/Examples/python/constants/index.html @@ -0,0 +1,67 @@ +<html> +<head> +<title>SWIG:Examples:python:constants</title> +</head> + +<body bgcolor="#ffffff"> + +<tt>SWIG/Examples/python/constants/</tt> +<hr> + +<H2>Wrapping C Constants</H2> + +<p> +When SWIG encounters C preprocessor macros and C declarations that look like constants, +it creates Python variables with an identical value. Click <a href="example.i">here</a> +to see a SWIG interface with some constant declarations in it. + +<h2>Accessing Constants from Python</h2> + +Click <a href="example.py">here</a> to see a script that prints out the values +of the constants contained in the above file. + +<h2>Key points</h2> + +<ul> +<li>The values of preprocessor macros are converted into Python constants. +<li>Types are inferred by syntax (e.g., "3" is an integer and "3.5" is a float). +<li>Character constants such as 'x' are converted into Python strings. +<li>C string literals such as "Hello World" are converted into Python strings. +<li>Macros that are not fully defined are simply ignored. For example: +<blockquote> +<pre> +#define EXTERN extern +</pre> +</blockquote> +is ignored because SWIG has no idea what type of variable this would be. + +<p> +<li>Expressions are allowed provided that all of their components are defined. Otherwise, the constant is ignored. + +<li>Certain C declarations involving 'const' are also turned into Python constants. +<li>The Python variables that SWIG creates are not protected from modification. For example, +even if you had this: +<blockquote> +<pre> +#define FOO 73 +</pre> +</blockquote> +a user could come along in a script and type +<blockquote> +<pre> +example.FOO = 13 +</pre> +</blockquote> +Unfortunately, there's no easy way to prevent this. + +<p> +<li>The constants that appear in a SWIG interface file do not have to appear in any sort +of matching C source file since the creation of a constant does not require linkage +to a stored value (i.e., a value held in a C global variable or memory location). +</ul> + +<hr> + + +</body> +</html> diff --git a/trunk/Examples/python/constants/runme.py b/trunk/Examples/python/constants/runme.py new file mode 100644 index 000000000..8d25b878b --- /dev/null +++ b/trunk/Examples/python/constants/runme.py @@ -0,0 +1,27 @@ +# file: runme.py + +import example + +print "ICONST =", example.ICONST, "(should be 42)" +print "FCONST =", example.FCONST, "(should be 2.1828)" +print "CCONST =", example.CCONST, "(should be 'x')" +print "CCONST2 =", example.CCONST2, "(this should be on a new line)" +print "SCONST =", example.SCONST, "(should be 'Hello World')" +print "SCONST2 =", example.SCONST2, "(should be '\"Hello World\"')" +print "EXPR =", example.EXPR, "(should be 48.5484)" +print "iconst =", example.iconst, "(should be 37)" +print "fconst =", example.fconst, "(should be 3.14)" + +try: + print "EXTERN = ", example.EXTERN, "(Arg! This shouldn't print anything)" +except AttributeError: + print "EXTERN isn't defined (good)" + +try: + print "FOO = ", example.FOO, "(Arg! This shouldn't print anything)" +except AttributeError: + print "FOO isn't defined (good)" + + + + diff --git a/trunk/Examples/python/contract/Makefile b/trunk/Examples/python/contract/Makefile new file mode 100644 index 000000000..77fe94b1a --- /dev/null +++ b/trunk/Examples/python/contract/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +SWIGOPT = +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/contract/example.c b/trunk/Examples/python/contract/example.c new file mode 100644 index 000000000..1a644543f --- /dev/null +++ b/trunk/Examples/python/contract/example.c @@ -0,0 +1,23 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +int fact(int n) { + if (n <= 0) return 1; + return n*fact(n-1); +} + + diff --git a/trunk/Examples/python/contract/example.dsp b/trunk/Examples/python/contract/example.dsp new file mode 100644 index 000000000..32845e0e8 --- /dev/null +++ b/trunk/Examples/python/contract/example.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=example - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "example.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "example - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /debug /machine:I386 /out:"_example.pyd" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "example - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /machine:I386 /out:"_example.pyd"
+
+!ENDIF
+
+# Begin Target
+
+# Name "example - Win32 Debug"
+# Name "example - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\example.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\example_wrap.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Source File
+
+SOURCE=.\example.i
+
+!IF "$(CFG)" == "example - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\example.i
+InputName=example
+
+"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -python $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "example - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\example.i
+InputName=example
+
+"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -python $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/trunk/Examples/python/contract/example.i b/trunk/Examples/python/contract/example.i new file mode 100644 index 000000000..8fd1a80af --- /dev/null +++ b/trunk/Examples/python/contract/example.i @@ -0,0 +1,21 @@ +/* File : example.i */ +%module example + +%contract gcd(int x, int y) { +require: + x >= 0; + y >= 0; +} + +%contract fact(int n) { +require: + n >= 0; +ensure: + fact >= 1; +} + +%inline %{ +extern int gcd(int x, int y); +extern int fact(int n); +extern double Foo; +%} diff --git a/trunk/Examples/python/contract/runme.py b/trunk/Examples/python/contract/runme.py new file mode 100644 index 000000000..d484ae916 --- /dev/null +++ b/trunk/Examples/python/contract/runme.py @@ -0,0 +1,30 @@ +# file: runme.py + +import example + +# Call our gcd() function + +x = 42 +y = 105 +g = example.gcd(x,y) +print "The gcd of %d and %d is %d" % (x,y,g) + +# Manipulate the Foo global variable + +# Output its current value +print "Foo = ", example.cvar.Foo + +# Change its value +example.cvar.Foo = 3.1415926 + +# See if the change took effect +print "Foo = ", example.cvar.Foo + + + + + + + + + diff --git a/trunk/Examples/python/docstrings/Makefile b/trunk/Examples/python/docstrings/Makefile new file mode 100644 index 000000000..f25450cac --- /dev/null +++ b/trunk/Examples/python/docstrings/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = -O + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/docstrings/example.cxx b/trunk/Examples/python/docstrings/example.cxx new file mode 100644 index 000000000..93e65421c --- /dev/null +++ b/trunk/Examples/python/docstrings/example.cxx @@ -0,0 +1,4 @@ +#include "example.h" + +void Foo::bar() {} + diff --git a/trunk/Examples/python/docstrings/example.h b/trunk/Examples/python/docstrings/example.h new file mode 100644 index 000000000..f44dbc4d3 --- /dev/null +++ b/trunk/Examples/python/docstrings/example.h @@ -0,0 +1,4 @@ +class Foo { + public: + void bar(); +}; diff --git a/trunk/Examples/python/docstrings/example.i b/trunk/Examples/python/docstrings/example.i new file mode 100644 index 000000000..15e08e641 --- /dev/null +++ b/trunk/Examples/python/docstrings/example.i @@ -0,0 +1,14 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* %feature("docstring") has to come before the declaration of the method to + * SWIG. */ +%feature("docstring") Foo::bar "No comment" + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/trunk/Examples/python/docstrings/runme.py b/trunk/Examples/python/docstrings/runme.py new file mode 100644 index 000000000..b6c95e613 --- /dev/null +++ b/trunk/Examples/python/docstrings/runme.py @@ -0,0 +1,6 @@ +# file: runme.py + +import example + +print "example.Foo.bar.__doc__ =", repr(example.Foo.bar.__doc__), "(Should be 'No comment')" + diff --git a/trunk/Examples/python/enum/Makefile b/trunk/Examples/python/enum/Makefile new file mode 100644 index 000000000..74625b992 --- /dev/null +++ b/trunk/Examples/python/enum/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/enum/example.cxx b/trunk/Examples/python/enum/example.cxx new file mode 100644 index 000000000..6785e57ac --- /dev/null +++ b/trunk/Examples/python/enum/example.cxx @@ -0,0 +1,37 @@ +/* File : example.c */ + +#include "example.h" +#include <stdio.h> + +void Foo::enum_test(speed s) { + if (s == IMPULSE) { + printf("IMPULSE speed\n"); + } else if (s == WARP) { + printf("WARP speed\n"); + } else if (s == LUDICROUS) { + printf("LUDICROUS speed\n"); + } else { + printf("Unknown speed\n"); + } +} + +void enum_test(color c, Foo::speed s) { + if (c == RED) { + printf("color = RED, "); + } else if (c == BLUE) { + printf("color = BLUE, "); + } else if (c == GREEN) { + printf("color = GREEN, "); + } else { + printf("color = Unknown color!, "); + } + if (s == Foo::IMPULSE) { + printf("speed = IMPULSE speed\n"); + } else if (s == Foo::WARP) { + printf("speed = WARP speed\n"); + } else if (s == Foo::LUDICROUS) { + printf("speed = LUDICROUS speed\n"); + } else { + printf("speed = Unknown speed!\n"); + } +} diff --git a/trunk/Examples/python/enum/example.h b/trunk/Examples/python/enum/example.h new file mode 100644 index 000000000..525d62afc --- /dev/null +++ b/trunk/Examples/python/enum/example.h @@ -0,0 +1,13 @@ +/* File : example.h */ + +enum color { RED, BLUE, GREEN }; + +class Foo { + public: + Foo() { } + enum speed { IMPULSE, WARP, LUDICROUS }; + void enum_test(speed s); +}; + +void enum_test(color c, Foo::speed s); + diff --git a/trunk/Examples/python/enum/example.i b/trunk/Examples/python/enum/example.i new file mode 100644 index 000000000..23ee8a822 --- /dev/null +++ b/trunk/Examples/python/enum/example.i @@ -0,0 +1,11 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ + +%include "example.h" + diff --git a/trunk/Examples/python/enum/index.html b/trunk/Examples/python/enum/index.html new file mode 100644 index 000000000..776030ffa --- /dev/null +++ b/trunk/Examples/python/enum/index.html @@ -0,0 +1,35 @@ +<html> +<head> +<title>SWIG:Examples:python:enum</title> +</head> + +<body bgcolor="#ffffff"> + + +<tt>SWIG/Examples/python/enum/</tt> +<hr> + +<H2>Wrapping enumerations</H2> + +<p> +This example tests SWIG's ability to wrap enumerations. By default, SWIG +converts enumeration specifications into integer constants. Further use +of enumerated types are handled as integers. + +<ul> +<li><a href="example.h">example.h</a>. Header file containing some enums. +<li><a href="example.i">example.i</a>. Interface file. +<li><a href="example.py">example.py</a>. Sample Python script. +</ul> + +<h2>Notes</h2> + +<ul> +<li>SWIG allows arbitrary integers to be passed as enum values. However, +the result of passing an integer not corresponding to any of the values +specified in the <tt>enum</tt> specification is undefined. +</ul> + +<hr> +</body> +</html> diff --git a/trunk/Examples/python/enum/runme.py b/trunk/Examples/python/enum/runme.py new file mode 100644 index 000000000..10c4a260d --- /dev/null +++ b/trunk/Examples/python/enum/runme.py @@ -0,0 +1,31 @@ +# file: runme.py + +import example + +# ----- Object creation ----- + +# Print out the value of some enums +print "*** color ***" +print " RED =", example.RED +print " BLUE =", example.BLUE +print " GREEN =", example.GREEN + +print "\n*** Foo::speed ***" +print " Foo_IMPULSE =", example.Foo.IMPULSE +print " Foo_WARP =", example.Foo.WARP +print " Foo_LUDICROUS =", example.Foo.LUDICROUS + +print "\nTesting use of enums with functions\n" + +example.enum_test(example.RED, example.Foo.IMPULSE) +example.enum_test(example.BLUE, example.Foo.WARP) +example.enum_test(example.GREEN, example.Foo.LUDICROUS) +example.enum_test(1234,5678) + +print "\nTesting use of enum with class method" +f = example.Foo() + +f.enum_test(example.Foo.IMPULSE) +f.enum_test(example.Foo.WARP) +f.enum_test(example.Foo.LUDICROUS) + diff --git a/trunk/Examples/python/exception/Makefile b/trunk/Examples/python/exception/Makefile new file mode 100644 index 000000000..7dbdde944 --- /dev/null +++ b/trunk/Examples/python/exception/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/exception/example.h b/trunk/Examples/python/exception/example.h new file mode 100644 index 000000000..8f9a977b0 --- /dev/null +++ b/trunk/Examples/python/exception/example.h @@ -0,0 +1,53 @@ +/* File : example.h */ + +#include <string> +#ifndef SWIG +struct A { +}; +#endif + +class Exc { +public: + Exc(int c, const char *m) { + code = c; + strncpy(msg,m,256); + } + int code; + char msg[256]; +}; + +#if defined(_MSC_VER) + #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + +class Test { +public: + int simple() throw(int) { + throw(37); + return 1; + } + int message() throw(const char *) { + throw("I died."); + return 1; + } + int hosed() throw(Exc) { + throw(Exc(42,"Hosed")); + return 1; + } + int unknown() throw(A*) { + static A a; + throw &a; + return 1; + } + int multi(int x) throw(int, const char *, Exc) { + if (x == 1) throw(37); + if (x == 2) throw("Bleah!"); + if (x == 3) throw(Exc(42,"No-go-diggy-die")); + return 1; + } +}; + +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + diff --git a/trunk/Examples/python/exception/example.i b/trunk/Examples/python/exception/example.i new file mode 100644 index 000000000..08672c3a8 --- /dev/null +++ b/trunk/Examples/python/exception/example.i @@ -0,0 +1,12 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%include "std_string.i" + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/trunk/Examples/python/exception/runme.py b/trunk/Examples/python/exception/runme.py new file mode 100644 index 000000000..718707861 --- /dev/null +++ b/trunk/Examples/python/exception/runme.py @@ -0,0 +1,36 @@ +# file: runme.py + +# Throw a lot of exceptions + +import example + +t = example.Test() +try: + t.unknown() +except RuntimeError,e: + print "incomplete type", e.args[0] + +try: + t.simple() +except RuntimeError,e: + print e.args[0] + +try: + t.message() +except RuntimeError,e: + print e.args[0] + +try: + t.hosed() +except example.Exc,e: + print e.code, e.msg + +for i in range(1,4): + try: + t.multi(i) + except RuntimeError,e: + print e.args[0] + except example.Exc,e: + print e.code, e.msg + + diff --git a/trunk/Examples/python/exceptproxy/Makefile b/trunk/Examples/python/exceptproxy/Makefile new file mode 100644 index 000000000..ba5c79827 --- /dev/null +++ b/trunk/Examples/python/exceptproxy/Makefile @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/exceptproxy/example.h b/trunk/Examples/python/exceptproxy/example.h new file mode 100644 index 000000000..ec7107a5e --- /dev/null +++ b/trunk/Examples/python/exceptproxy/example.h @@ -0,0 +1,54 @@ +/* File : example.h */ + +// A simple exception +class EmptyError { }; +class FullError { + public: + int maxsize; + FullError(int m) : maxsize(m) { } +}; + +#if defined(_MSC_VER) + #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + +template<typename T> class Queue { + int maxsize; + T *items; + int nitems; + int last; + public: + Queue(int size) { + maxsize = size; + items = new T[size]; + nitems = 0; + last = 0; + } + ~Queue() { + delete [] items; + } + void enqueue(T x) throw(FullError) { + if (nitems == maxsize) { + throw FullError(maxsize); + } + items[last] = x; + last = (last + 1) % maxsize; + nitems++; + } + T dequeue() { + T x; + if (nitems == 0) throw EmptyError(); + x = items[(last + maxsize - nitems) % maxsize]; + nitems--; + return x; + } + int length() { + return nitems; + } +}; + + +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + diff --git a/trunk/Examples/python/exceptproxy/example.i b/trunk/Examples/python/exceptproxy/example.i new file mode 100644 index 000000000..4a1e0bae9 --- /dev/null +++ b/trunk/Examples/python/exceptproxy/example.i @@ -0,0 +1,114 @@ +/* This is a rather sophisticated example that illustrates exception handling, + templates, and proxy classes. + + (i) The %exception directive is used to attach exception handlers + to specific methods. + + (ii) Exception classes are automatically converted to proxy class + objects. + + (iii) The %template directive is used to expand the templates +*/ + +%module example + +%{ +#include "example.h" +%} + +/* Define some exception handlers for specific methods. In + the header file, the enqueue method throws FullError and + the dequeue method throws EmptyError. Since we don't + want to define an exception handler for everything, we + simply write a handler each method individually. + + Note: the *::enqueue syntax means that we simply define + the handler for any class with this method defined. +*/ + +/* + First we need to 'disable' the default swig throw mechanism for the + FullError class. We do this by rethrowing the exception. + + Note that this is necessary since the class appears in a throw + declaration: + + + void enqueue(T x) throw(FullError); + + hence, swig recognizes it as an exception class and it will generate + the necessary code to catch it and rethrow it to the python side. + +*/ +%typemap(throws) FullError "(void)$1; throw;"; + + +%exception *::enqueue { + try { + $action + } catch(FullError& e) { + FullError *ecopy = new FullError(e); + PyObject *err = SWIG_NewPointerObj(ecopy, SWIGTYPE_p_FullError, 1); + PyErr_SetObject(SWIG_Python_ExceptionType(SWIGTYPE_p_FullError), err); + SWIG_fail; + } +} + +/* Some notes about the code above: + + (0) $action gets replaced with the actual method call. + + (1) We are going to return a copy of the exception object (FullError) + to pass back to the Python interpreter. This is why the copy + constructor is being called. + + (2) The SWIG_NewPointerObj() call automatically wraps the exception object + into a proxy class. The SWIGTYPE_p_FullError is the type-descriptor + used for type checking. The "1" indicates that Python will have + ownership of the resulting object. + + (3) The PyErr_SetObject call sets the Python exception. However, + the SWIGTYPE_p_FullError->clientdata reference may not be + obvious. This is actually the Python proxy class object + for FullError. Recall that in Python, exceptions are defined + as classes. Therefore, this works perfectly as the argument to + PyErr_SetObject()! A neat trick perhaps. +*/ + +/* + Now, the EmpytError doesn't appear in a throw declaration, and hence + we need to 'mark' it as an exception class. In python, classes that + are used as exception are 'special', and need to be wrapped as + 'classic' ones. + + This is a python issue, and if you don't mark the class, you will + see 'interesting' behaviours at the python side. + + +*/ +%exceptionclass EmptyError; +%exceptionclass FullError; + +%exception *::dequeue { + try { + $action + } catch(EmptyError& e) { + EmptyError *ecopy = new EmptyError(e); + PyObject *err = SWIG_NewPointerObj(ecopy, SWIGTYPE_p_EmptyError, 1); + PyErr_SetObject(SWIG_Python_ExceptionType(SWIGTYPE_p_EmptyError), err); + SWIG_fail; + } +} + +/* Grab the original header file */ +%include "example.h" + +/* Instantiate a few templates */ + +%template(intQueue) Queue<int>; +%template(doubleQueue) Queue<double>; + + + + + diff --git a/trunk/Examples/python/exceptproxy/runme.py b/trunk/Examples/python/exceptproxy/runme.py new file mode 100644 index 000000000..a2ae55584 --- /dev/null +++ b/trunk/Examples/python/exceptproxy/runme.py @@ -0,0 +1,45 @@ +# file: runme.py +import example + +q = example.intQueue(10) + +print "Inserting items into intQueue" + +try: + for i in range(0,100): + q.enqueue(i) +except example.FullError,e: + print "Maxsize is", e.maxsize + +print "Removing items" + +try: + while 1: + q.dequeue() +except example.EmptyError,e: + pass + + +q = example.doubleQueue(1000) + +print "Inserting items into doubleQueue" + +try: + for i in range(0,10000): + q.enqueue(i*1.5) +except example.FullError,e: + print "Maxsize is", e.maxsize + +print "Removing items" + +try: + while 1: + q.dequeue() +except example.EmptyError,e: + pass + + + + + + diff --git a/trunk/Examples/python/extend/Makefile b/trunk/Examples/python/extend/Makefile new file mode 100644 index 000000000..a29276e58 --- /dev/null +++ b/trunk/Examples/python/extend/Makefile @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/extend/example.cxx b/trunk/Examples/python/extend/example.cxx new file mode 100644 index 000000000..450d75608 --- /dev/null +++ b/trunk/Examples/python/extend/example.cxx @@ -0,0 +1,4 @@ +/* File : example.cxx */ + +#include "example.h" + diff --git a/trunk/Examples/python/extend/example.h b/trunk/Examples/python/extend/example.h new file mode 100644 index 000000000..b27ab9711 --- /dev/null +++ b/trunk/Examples/python/extend/example.h @@ -0,0 +1,56 @@ +/* File : example.h */ + +#include <cstdio> +#include <iostream> +#include <vector> +#include <string> +#include <cmath> + +class Employee { +private: + std::string name; +public: + Employee(const char* n): name(n) {} + virtual std::string getTitle() { return getPosition() + " " + getName(); } + virtual std::string getName() { return name; } + virtual std::string getPosition() const { return "Employee"; } + virtual ~Employee() { printf("~Employee() @ %p\n", this); } +}; + + +class Manager: public Employee { +public: + Manager(const char* n): Employee(n) {} + virtual std::string getPosition() const { return "Manager"; } +}; + + +class EmployeeList { + std::vector<Employee*> list; +public: + EmployeeList() { + list.push_back(new Employee("Bob")); + list.push_back(new Employee("Jane")); + list.push_back(new Manager("Ted")); + } + void addEmployee(Employee *p) { + list.push_back(p); + std::cout << "New employee added. Current employees are:" << std::endl; + std::vector<Employee*>::iterator i; + for (i=list.begin(); i!=list.end(); i++) { + std::cout << " " << (*i)->getTitle() << std::endl; + } + } + const Employee *get_item(int i) { + return list[i]; + } + ~EmployeeList() { + std::vector<Employee*>::iterator i; + std::cout << "~EmployeeList, deleting " << list.size() << " employees." << std::endl; + for (i=list.begin(); i!=list.end(); i++) { + delete *i; + } + std::cout << "~EmployeeList empty." << std::endl; + } +}; + diff --git a/trunk/Examples/python/extend/example.i b/trunk/Examples/python/extend/example.i new file mode 100644 index 000000000..c8ec32e09 --- /dev/null +++ b/trunk/Examples/python/extend/example.i @@ -0,0 +1,15 @@ +/* File : example.i */ +%module(directors="1") example +%{ +#include "example.h" +%} + +%include "std_vector.i" +%include "std_string.i" + +/* turn on director wrapping for Manager */ +%feature("director") Employee; +%feature("director") Manager; + +%include "example.h" + diff --git a/trunk/Examples/python/extend/index.html b/trunk/Examples/python/extend/index.html new file mode 100644 index 000000000..959e8c63b --- /dev/null +++ b/trunk/Examples/python/extend/index.html @@ -0,0 +1,19 @@ +<html> +<head> +<title>SWIG:Examples:python:extend</title> +</head> + +<body bgcolor="#ffffff"> + + +<tt>SWIG/Examples/python/extend/</tt> +<hr> + +<H2>Extending a simple C++ class in Python</H2> + +<p> +This example illustrates the extending of a C++ class with cross language polymorphism. + +<hr> +</body> +</html> diff --git a/trunk/Examples/python/extend/runme.py b/trunk/Examples/python/extend/runme.py new file mode 100644 index 000000000..240b09894 --- /dev/null +++ b/trunk/Examples/python/extend/runme.py @@ -0,0 +1,81 @@ +# file: runme.py + +# This file illustrates the cross language polymorphism using directors. + +import example + + +# CEO class, which overrides Employee::getPosition(). + +class CEO(example.Manager): + def __init__(self, name): + example.Manager.__init__(self, name) + def getPosition(self): + return "CEO" + + +# Create an instance of our employee extension class, CEO. The calls to +# getName() and getPosition() are standard, the call to getTitle() uses +# the director wrappers to call CEO.getPosition. e = CEO("Alice") + +e = CEO("Alice") +print e.getName(), "is a", e.getPosition() +print "Just call her \"%s\"" % e.getTitle() +print "----------------------" + + +# Create a new EmployeeList instance. This class does not have a C++ +# director wrapper, but can be used freely with other classes that do. + +list = example.EmployeeList() + +# EmployeeList owns its items, so we must surrender ownership of objects +# we add. This involves first calling the __disown__ method to tell the +# C++ director to start reference counting. We reassign the resulting +# weakref.proxy to e so that no hard references remain. This can also be +# done when the object is constructed, as in: e = +# CEO("Alice").__disown__() + +e = e.__disown__() +list.addEmployee(e) +print "----------------------" + +# Now we access the first four items in list (three are C++ objects that +# EmployeeList's constructor adds, the last is our CEO). The virtual +# methods of all these instances are treated the same. For items 0, 1, and +# 2, both all methods resolve in C++. For item 3, our CEO, getTitle calls +# getPosition which resolves in Python. The call to getPosition is +# slightly different, however, from the e.getPosition() call above, since +# now the object reference has been "laundered" by passing through +# EmployeeList as an Employee*. Previously, Python resolved the call +# immediately in CEO, but now Python thinks the object is an instance of +# class Employee (actually EmployeePtr). So the call passes through the +# Employee proxy class and on to the C wrappers and C++ director, +# eventually ending up back at the CEO implementation of getPosition(). +# The call to getTitle() for item 3 runs the C++ Employee::getTitle() +# method, which in turn calls getPosition(). This virtual method call +# passes down through the C++ director class to the Python implementation +# in CEO. All this routing takes place transparently. + +print "(position, title) for items 0-3:" + +print " %s, \"%s\"" % (list.get_item(0).getPosition(), list.get_item(0).getTitle()) +print " %s, \"%s\"" % (list.get_item(1).getPosition(), list.get_item(1).getTitle()) +print " %s, \"%s\"" % (list.get_item(2).getPosition(), list.get_item(2).getTitle()) +print " %s, \"%s\"" % (list.get_item(3).getPosition(), list.get_item(3).getTitle()) +print "----------------------" + +# Time to delete the EmployeeList, which will delete all the Employee* +# items it contains. The last item is our CEO, which gets destroyed as its +# reference count goes to zero. The Python destructor runs, and is still +# able to call self.getName() since the underlying C++ object still +# exists. After this destructor runs the remaining C++ destructors run as +# usual to destroy the object. + +del list +print "----------------------" + +# All done. + +print "python exit" + diff --git a/trunk/Examples/python/funcptr/Makefile b/trunk/Examples/python/funcptr/Makefile new file mode 100644 index 000000000..0f4a1e077 --- /dev/null +++ b/trunk/Examples/python/funcptr/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-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:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/funcptr/example.c b/trunk/Examples/python/funcptr/example.c new file mode 100644 index 000000000..5c4a3dabf --- /dev/null +++ b/trunk/Examples/python/funcptr/example.c @@ -0,0 +1,19 @@ +/* File : example.c */ + +int do_op(int a, int b, int (*op)(int,int)) { + return (*op)(a,b); +} + +int add(int a, int b) { + return a+b; +} + +int sub(int a, int b) { + return a-b; +} + +int mul(int a, int b) { + return a*b; +} + +int (*funcvar)(int,int) = add; diff --git a/trunk/Examples/python/funcptr/example.h b/trunk/Examples/python/funcptr/example.h new file mode 100644 index 000000000..9936e24fc --- /dev/null +++ b/trunk/Examples/python/funcptr/example.h @@ -0,0 +1,9 @@ +/* file: example.h */ + +extern int do_op(int,int, int (*op)(int,int)); +extern int add(int,int); +extern int sub(int,int); +extern int mul(int,int); + +extern int (*funcvar)(int,int); + diff --git a/trunk/Examples/python/funcptr/example.i b/trunk/Examples/python/funcptr/example.i new file mode 100644 index 000000000..8b3bef678 --- /dev/null +++ b/trunk/Examples/python/funcptr/example.i @@ -0,0 +1,16 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Wrap a function taking a pointer to a function */ +extern int do_op(int a, int b, int (*op)(int, int)); + +/* Now install a bunch of "ops" as constants */ +%constant int (*ADD)(int,int) = add; +%constant int (*SUB)(int,int) = sub; +%constant int (*MUL)(int,int) = mul; + +extern int (*funcvar)(int,int); + diff --git a/trunk/Examples/python/funcptr/index.html b/trunk/Examples/python/funcptr/index.html new file mode 100644 index 000000000..e41e0db45 --- /dev/null +++ b/trunk/Examples/python/funcptr/index.html @@ -0,0 +1,90 @@ +<html> +<head> +<title>SWIG:Examples:python:funcptr</title> +</head> + +<body bgcolor="#ffffff"> + + +<tt>SWIG/Examples/python/funcptr/</tt> +<hr> + +<H2>Pointers to Functions</H2> + +<p> +Okay, just what in the heck does SWIG do with a declaration like this? + +<blockquote> +<pre> +int do_op(int a, int b, int (*op)(int, int)); +</pre> +</blockquote> + +Well, it creates a wrapper as usual. Of course, that does raise some +questions about the third argument (the pointer to a function). + +<p> +In this case, SWIG will wrap the function pointer as it does for all other +pointers. However, in order to actually call this function from a script, +you will need to pass some kind of C function pointer object. In C, +this is easy, you just supply a function name as an argument like this: + +<blockquote> +<pre> +/* Some callback function */ +int add(int a, int b) { + return a+b; +} +... +int r = do_op(x,y,add); +</pre> +</blockquote> + +To make this work with SWIG, you will need to do a little extra work. Specifically, +you need to create some function pointer objects using the %constant directive like this: + +<blockquote> +<pre> +%constant(int (*)(int,int)) ADD = add; +</pre> +</blockquote> + +Now, in a script, you would do this: + +<blockquote> +<pre> +r = do_op(x,y, ADD) +</pre> +</blockquote> + +<h2>An Example</h2> + +Here are some files that illustrate this with a simple example: + +<ul> +<li><a href="example.c">example.c</a> +<li><a href="example.h">example.h</a> +<li><a href="example.i">example.i</a> (SWIG interface) +<li><a href="example.py">example.py</a> (Sample script) +</ul> + +<h2>Notes</h2> + +<ul> +<li>The value of a function pointer must correspond to a function written in C or C++. +It is not possible to pass an arbitrary Python function object in as a substitute for a C +function pointer. + +<p> +<li>A python function can be used as a C/C++ callback if you write some +clever typemaps and are very careful about how you create your extension. +This is an advanced topic not covered here. +</ul> + +<hr> +</body> +</html> + + + + diff --git a/trunk/Examples/python/funcptr/runme.py b/trunk/Examples/python/funcptr/runme.py new file mode 100644 index 000000000..bce065057 --- /dev/null +++ b/trunk/Examples/python/funcptr/runme.py @@ -0,0 +1,20 @@ +# file: runme.py + +import example + +a = 37 +b = 42 + +# Now call our C function with a bunch of callbacks + +print "Trying some C callback functions" +print " a =", a +print " b =", b +print " ADD(a,b) =", example.do_op(a,b,example.ADD) +print " SUB(a,b) =", example.do_op(a,b,example.SUB) +print " MUL(a,b) =", example.do_op(a,b,example.MUL) + +print "Here is what the C callback function objects look like in Python" +print " ADD =", example.ADD +print " SUB =", example.SUB +print " MUL =", example.MUL diff --git a/trunk/Examples/python/funcptr2/Makefile b/trunk/Examples/python/funcptr2/Makefile new file mode 100644 index 000000000..0f4a1e077 --- /dev/null +++ b/trunk/Examples/python/funcptr2/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-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:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/funcptr2/example.c b/trunk/Examples/python/funcptr2/example.c new file mode 100644 index 000000000..5c4a3dabf --- /dev/null +++ b/trunk/Examples/python/funcptr2/example.c @@ -0,0 +1,19 @@ +/* File : example.c */ + +int do_op(int a, int b, int (*op)(int,int)) { + return (*op)(a,b); +} + +int add(int a, int b) { + return a+b; +} + +int sub(int a, int b) { + return a-b; +} + +int mul(int a, int b) { + return a*b; +} + +int (*funcvar)(int,int) = add; diff --git a/trunk/Examples/python/funcptr2/example.h b/trunk/Examples/python/funcptr2/example.h new file mode 100644 index 000000000..9936e24fc --- /dev/null +++ b/trunk/Examples/python/funcptr2/example.h @@ -0,0 +1,9 @@ +/* file: example.h */ + +extern int do_op(int,int, int (*op)(int,int)); +extern int add(int,int); +extern int sub(int,int); +extern int mul(int,int); + +extern int (*funcvar)(int,int); + diff --git a/trunk/Examples/python/funcptr2/example.i b/trunk/Examples/python/funcptr2/example.i new file mode 100644 index 000000000..681775a3e --- /dev/null +++ b/trunk/Examples/python/funcptr2/example.i @@ -0,0 +1,18 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Wrap a function taking a pointer to a function */ +extern int do_op(int a, int b, int (*op)(int, int)); + +/* Now install a bunch of "ops" as constants */ +%callback("%(upper)s"); +int add(int, int); +int sub(int, int); +int mul(int, int); +%nocallback; + +extern int (*funcvar)(int,int); + diff --git a/trunk/Examples/python/funcptr2/runme.py b/trunk/Examples/python/funcptr2/runme.py new file mode 100644 index 000000000..bd58fb620 --- /dev/null +++ b/trunk/Examples/python/funcptr2/runme.py @@ -0,0 +1,24 @@ +# file: runme.py + +import example + +a = 37 +b = 42 + +# Now call our C function with a bunch of callbacks + +print "Trying some C callback functions" +print " a =", a +print " b =", b +print " ADD(a,b) =", example.do_op(a,b,example.ADD) +print " SUB(a,b) =", example.do_op(a,b,example.SUB) +print " MUL(a,b) =", example.do_op(a,b,example.MUL) + +print "Here is what the C callback function objects look like in Python" +print " ADD =", example.ADD +print " SUB =", example.SUB +print " MUL =", example.MUL + +print "Call the functions directly..." +print " add(a,b) =", example.add(a,b) +print " sub(a,b) =", example.sub(a,b) diff --git a/trunk/Examples/python/functor/Makefile b/trunk/Examples/python/functor/Makefile new file mode 100644 index 000000000..fe389757a --- /dev/null +++ b/trunk/Examples/python/functor/Makefile @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/functor/example.i b/trunk/Examples/python/functor/example.i new file mode 100644 index 000000000..2fd38176f --- /dev/null +++ b/trunk/Examples/python/functor/example.i @@ -0,0 +1,29 @@ +/* File : example.i */ +%module example + + +%inline %{ +// From B. Strousjoup, "The C++ Programming Language, Third Edition", p. 514 +template<class T> class Sum { + T res; +public: + Sum(T i = 0) : res(i) { } + void operator() (T x) { res += x; } + T result() const { return res; } +}; + +%} + +// Rename the application operator to __call__ for python. +// Note: this is normally automatic, but if you had to do it yourself +// you would use this directive: +// +// %rename(__call__) *::operator(); + +// Instantiate a few versions +%template(intSum) Sum<int>; +%template(doubleSum) Sum<double>; + + + + diff --git a/trunk/Examples/python/functor/runme.py b/trunk/Examples/python/functor/runme.py new file mode 100644 index 000000000..8fc0f2ff2 --- /dev/null +++ b/trunk/Examples/python/functor/runme.py @@ -0,0 +1,17 @@ +# Operator overloading example +import example +import math + +a = example.intSum(0) +b = example.doubleSum(100.0) + +# Use the objects. They should be callable just like a normal +# python function. + +for i in range(0,100): + a(i) # Note: function call + b(math.sqrt(i)) # Note: function call + +print a.result() +print b.result() + diff --git a/trunk/Examples/python/import/Makefile b/trunk/Examples/python/import/Makefile new file mode 100644 index 000000000..74d4f88cf --- /dev/null +++ b/trunk/Examples/python/import/Makefile @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SWIGOPT = +LIBS = + +all:: + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + LIBS='$(LIBS)' TARGET='base' INTERFACE='base.i' python_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + LIBS='$(LIBS)' TARGET='foo' INTERFACE='foo.i' python_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + LIBS='$(LIBS)' TARGET='bar' INTERFACE='bar.i' python_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + LIBS='$(LIBS)' TARGET='spam' INTERFACE='spam.i' python_cpp + + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + @rm -f foo.py bar.py spam.py base.py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/import/README b/trunk/Examples/python/import/README new file mode 100644 index 000000000..5679dbb7f --- /dev/null +++ b/trunk/Examples/python/import/README @@ -0,0 +1,39 @@ +This example tests the %import directive and working with multiple modules. + +Use 'python runme.py' to run a test. + +Overview: +--------- + +The example defines 4 different extension modules--each wrapping +a separate C++ class. + + base.i - Base class + foo.i - Foo class derived from Base + bar.i - Bar class derived from Base + spam.i - Spam class derived from Bar + +Each module uses %import to refer to another module. For +example, the 'foo.i' module uses '%import base.i' to get +definitions for its base class. + +If everything is okay, all of the modules will load properly and +type checking will work correctly. Caveat: Some compilers, for example +gcc-3.2.x, generate broken vtables with the inline methods in this test. +This is not a SWIG problem and can usually be solved with non-inlined +destructors compiled into separate shared objects/DLLs. + +Unix: +----- +- Run make +- Run the test as described above + +Windows: +-------- +- Use the Visual C++ 6 workspace file (example.dsw). Build the runtime + project DLL first followed by the other 4 DLLs as they all have a + dependency on the runtime DLL. The Batch build option in the Build menu + is usually the easiest way to do this. Only use the Release builds not + the Debug builds. +- Run the test as described above + diff --git a/trunk/Examples/python/import/bar.dsp b/trunk/Examples/python/import/bar.dsp new file mode 100644 index 000000000..17b05cc39 --- /dev/null +++ b/trunk/Examples/python/import/bar.dsp @@ -0,0 +1,144 @@ +# Microsoft Developer Studio Project File - Name="bar" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=bar - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "bar.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "bar.mak" CFG="bar - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "bar - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "bar - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "bar - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BAR_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GR /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BAR_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /debug /machine:I386 /out:"_bar.pyd" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "bar - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BAR_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BAR_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /machine:I386 /out:"_bar.pyd"
+
+!ENDIF
+
+# Begin Target
+
+# Name "bar - Win32 Debug"
+# Name "bar - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\bar_wrap.cxx
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\bar.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\bar.i
+
+!IF "$(CFG)" == "bar - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\bar.i
+InputName=bar
+
+"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -c++ -python $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "bar - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\bar.i
+InputName=bar
+
+"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -c++ -python $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/trunk/Examples/python/import/bar.h b/trunk/Examples/python/import/bar.h new file mode 100644 index 000000000..fa4185f1f --- /dev/null +++ b/trunk/Examples/python/import/bar.h @@ -0,0 +1,22 @@ +#include "base.h" + +class Bar : public Base { + public: + Bar() { } + ~Bar() { } + virtual void A() { + printf("I'm Bar::A\n"); + } + void B() { + printf("I'm Bar::B\n"); + } + virtual Base *toBase() { + return static_cast<Base *>(this); + } + static Bar *fromBase(Base *b) { + return dynamic_cast<Bar *>(b); + } + +}; + + diff --git a/trunk/Examples/python/import/bar.i b/trunk/Examples/python/import/bar.i new file mode 100644 index 000000000..5816cbe17 --- /dev/null +++ b/trunk/Examples/python/import/bar.i @@ -0,0 +1,9 @@ +%module bar +%{ +#include "bar.h" +%} + +%import base.i +%include "bar.h" + + diff --git a/trunk/Examples/python/import/base.dsp b/trunk/Examples/python/import/base.dsp new file mode 100644 index 000000000..2bc9736d1 --- /dev/null +++ b/trunk/Examples/python/import/base.dsp @@ -0,0 +1,144 @@ +# Microsoft Developer Studio Project File - Name="base" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=base - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "base.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "base.mak" CFG="base - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "base - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "base - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "base - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BASE_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GR /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BASE_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /debug /machine:I386 /out:"_base.pyd" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "base - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BASE_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BASE_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /machine:I386 /out:"_base.pyd"
+
+!ENDIF
+
+# Begin Target
+
+# Name "base - Win32 Debug"
+# Name "base - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\base_wrap.cxx
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\base.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\base.i
+
+!IF "$(CFG)" == "base - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\base.i
+InputName=base
+
+"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -c++ -python $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "base - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\base.i
+InputName=base
+
+"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -c++ -python $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/trunk/Examples/python/import/base.h b/trunk/Examples/python/import/base.h new file mode 100644 index 000000000..5a266f68c --- /dev/null +++ b/trunk/Examples/python/import/base.h @@ -0,0 +1,18 @@ +#include <stdio.h> + +class Base { + public: + Base() { }; + virtual ~Base() { }; + virtual void A() { + printf("I'm Base::A\n"); + } + void B() { + printf("I'm Base::B\n"); + } + virtual Base *toBase() { + return static_cast<Base *>(this); + } +}; + + diff --git a/trunk/Examples/python/import/base.i b/trunk/Examples/python/import/base.i new file mode 100644 index 000000000..f6e19efd8 --- /dev/null +++ b/trunk/Examples/python/import/base.i @@ -0,0 +1,6 @@ +%module base +%{ +#include "base.h" +%} + +%include base.h diff --git a/trunk/Examples/python/import/example.dsw b/trunk/Examples/python/import/example.dsw new file mode 100644 index 000000000..d395d464b --- /dev/null +++ b/trunk/Examples/python/import/example.dsw @@ -0,0 +1,65 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "bar"=.\bar.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "base"=.\base.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "foo"=.\foo.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "spam"=.\spam.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/trunk/Examples/python/import/foo.dsp b/trunk/Examples/python/import/foo.dsp new file mode 100644 index 000000000..9a92c4b85 --- /dev/null +++ b/trunk/Examples/python/import/foo.dsp @@ -0,0 +1,144 @@ +# Microsoft Developer Studio Project File - Name="foo" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=foo - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "foo.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "foo.mak" CFG="foo - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "foo - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "foo - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "foo - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GR /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /debug /machine:I386 /out:"_foo.pyd" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "foo - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /machine:I386 /out:"_foo.pyd"
+
+!ENDIF
+
+# Begin Target
+
+# Name "foo - Win32 Debug"
+# Name "foo - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\foo_wrap.cxx
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\foo.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\foo.i
+
+!IF "$(CFG)" == "foo - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\foo.i
+InputName=foo
+
+"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -c++ -python $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "foo - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\foo.i
+InputName=foo
+
+"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -c++ -python $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/trunk/Examples/python/import/foo.h b/trunk/Examples/python/import/foo.h new file mode 100644 index 000000000..dd5184031 --- /dev/null +++ b/trunk/Examples/python/import/foo.h @@ -0,0 +1,21 @@ +#include "base.h" + +class Foo : public Base { + public: + Foo() { } + ~Foo() { } + virtual void A() { + printf("I'm Foo::A\n"); + } + void B() { + printf("I'm Foo::B\n"); + } + virtual Base *toBase() { + return static_cast<Base *>(this); + } + static Foo *fromBase(Base *b) { + return dynamic_cast<Foo *>(b); + } +}; + + diff --git a/trunk/Examples/python/import/foo.i b/trunk/Examples/python/import/foo.i new file mode 100644 index 000000000..27feb2e6a --- /dev/null +++ b/trunk/Examples/python/import/foo.i @@ -0,0 +1,8 @@ +%module foo +%{ +#include "foo.h" +%} + +%import base.i +%include "foo.h" + diff --git a/trunk/Examples/python/import/runme.py b/trunk/Examples/python/import/runme.py new file mode 100644 index 000000000..6b800ecb8 --- /dev/null +++ b/trunk/Examples/python/import/runme.py @@ -0,0 +1,111 @@ +# file: runme.py +# Test various properties of classes defined in separate modules + +print "Testing the %import directive" +import base +import foo +import bar +import spam + +# Create some objects + +print "Creating some objects" + +a = base.Base() +b = foo.Foo() +c = bar.Bar() +d = spam.Spam() + +# Try calling some methods +print "Testing some methods" +print "", +print "Should see 'Base::A' ---> ", +a.A() +print "Should see 'Base::B' ---> ", +a.B() + +print "Should see 'Foo::A' ---> ", +b.A() +print "Should see 'Foo::B' ---> ", +b.B() + +print "Should see 'Bar::A' ---> ", +c.A() +print "Should see 'Bar::B' ---> ", +c.B() + +print "Should see 'Spam::A' ---> ", +d.A() +print "Should see 'Spam::B' ---> ", +d.B() + +# Try some casts + +print "\nTesting some casts\n" +print "", + +x = a.toBase() +print "Should see 'Base::A' ---> ", +x.A() +print "Should see 'Base::B' ---> ", +x.B() + +x = b.toBase() +print "Should see 'Foo::A' ---> ", +x.A() + +print "Should see 'Base::B' ---> ", +x.B() + +x = c.toBase() +print "Should see 'Bar::A' ---> ", +x.A() + +print "Should see 'Base::B' ---> ", +x.B() + +x = d.toBase() +print "Should see 'Spam::A' ---> ", +x.A() + +print "Should see 'Base::B' ---> ", +x.B() + +x = d.toBar() +print "Should see 'Bar::B' ---> ", +x.B() + +print "\nTesting some dynamic casts\n" +x = d.toBase() + +print " Spam -> Base -> Foo : ", +y = foo.Foo_fromBase(x) +if y: + print "bad swig" +else: + print "good swig" + +print " Spam -> Base -> Bar : ", +y = bar.Bar_fromBase(x) +if y: + print "good swig" +else: + print "bad swig" + +print " Spam -> Base -> Spam : ", +y = spam.Spam_fromBase(x) +if y: + print "good swig" +else: + print "bad swig" + +print " Foo -> Spam : ", +y = spam.Spam_fromBase(b) +if y: + print "bad swig" +else: + print "good swig" + + + + diff --git a/trunk/Examples/python/import/spam.dsp b/trunk/Examples/python/import/spam.dsp new file mode 100644 index 000000000..0a6595bfe --- /dev/null +++ b/trunk/Examples/python/import/spam.dsp @@ -0,0 +1,144 @@ +# Microsoft Developer Studio Project File - Name="spam" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=spam - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "spam.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "spam.mak" CFG="spam - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "spam - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "spam - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "spam - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAM_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GR /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAM_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /debug /machine:I386 /out:"_spam.pyd" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "spam - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAM_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAM_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /machine:I386 /out:"_spam.pyd"
+
+!ENDIF
+
+# Begin Target
+
+# Name "spam - Win32 Debug"
+# Name "spam - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\spam_wrap.cxx
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\spam.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\spam.i
+
+!IF "$(CFG)" == "spam - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\spam.i
+InputName=spam
+
+"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -c++ -python $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "spam - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\spam.i
+InputName=spam
+
+"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -c++ -python $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/trunk/Examples/python/import/spam.h b/trunk/Examples/python/import/spam.h new file mode 100644 index 000000000..b4e7a2646 --- /dev/null +++ b/trunk/Examples/python/import/spam.h @@ -0,0 +1,24 @@ +#include "bar.h" + +class Spam : public Bar { + public: + Spam() { } + ~Spam() { } + virtual void A() { + printf("I'm Spam::A\n"); + } + void B() { + printf("I'm Spam::B\n"); + } + virtual Base *toBase() { + return static_cast<Base *>(this); + } + virtual Bar *toBar() { + return static_cast<Bar *>(this); + } + static Spam *fromBase(Base *b) { + return dynamic_cast<Spam *>(b); + } +}; + + diff --git a/trunk/Examples/python/import/spam.i b/trunk/Examples/python/import/spam.i new file mode 100644 index 000000000..d3d9121db --- /dev/null +++ b/trunk/Examples/python/import/spam.i @@ -0,0 +1,9 @@ +%module spam +%{ +#include "spam.h" +%} + +%import bar.i +%include "spam.h" + + diff --git a/trunk/Examples/python/import_template/Makefile b/trunk/Examples/python/import_template/Makefile new file mode 100644 index 000000000..ee47e994d --- /dev/null +++ b/trunk/Examples/python/import_template/Makefile @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SWIGOPT = +LIBS = + +all:: + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + LIBS='$(LIBS)' TARGET='base' INTERFACE='base.i' python_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + LIBS='$(LIBS)' TARGET='foo' INTERFACE='foo.i' python_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + LIBS='$(LIBS)' TARGET='bar' INTERFACE='bar.i' python_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + LIBS='$(LIBS)' TARGET='spam' INTERFACE='spam.i' python_cpp + + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + @rm -f foo.py bar.py spam.py base.py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/import_template/README b/trunk/Examples/python/import_template/README new file mode 100644 index 000000000..f8cf02dc7 --- /dev/null +++ b/trunk/Examples/python/import_template/README @@ -0,0 +1,30 @@ +This example tests the %import directive and working with multiple modules. + +Use 'python runme.py' to run a test. + +Overview: +--------- + +The example defines 4 different extension modules--each wrapping +a separate C++ class. + + base.i - Base class + foo.i - Foo class derived from Base + bar.i - Bar class derived from Base + spam.i - Spam class derived from Bar + +Each module uses %import to refer to another module. For +example, the 'foo.i' module uses '%import base.i' to get +definitions for its base class. + +If everything is okay, all of the modules will load properly and +type checking will work correctly. Caveat: Some compilers, for example +gcc-3.2.x, generate broken vtables with the inline methods in this test. +This is not a SWIG problem and can usually be solved with non-inlined +destructors compiled into separate shared objects/DLLs. + +Unix: +----- +- Run make +- Run the test as described above + diff --git a/trunk/Examples/python/import_template/bar.h b/trunk/Examples/python/import_template/bar.h new file mode 100644 index 000000000..500b67a3c --- /dev/null +++ b/trunk/Examples/python/import_template/bar.h @@ -0,0 +1,22 @@ +#include "base.h" + +template<class T> class Bar : public Base<T> { + public: + Bar() { } + ~Bar() { } + virtual void A() { + printf("I'm Bar::A\n"); + } + void B() { + printf("I'm Bar::B\n"); + } + virtual Base<T> *toBase() { + return static_cast<Base<T> *>(this); + } + static Bar<T> *fromBase(Base<T> *b) { + return dynamic_cast<Bar<T> *>(b); + } + +}; + + diff --git a/trunk/Examples/python/import_template/bar.i b/trunk/Examples/python/import_template/bar.i new file mode 100644 index 000000000..155c08d34 --- /dev/null +++ b/trunk/Examples/python/import_template/bar.i @@ -0,0 +1,11 @@ +%module bar +%{ +#include "bar.h" +%} + +%import base.i +%include "bar.h" + +%template(intBar) Bar<int>; + + diff --git a/trunk/Examples/python/import_template/base.h b/trunk/Examples/python/import_template/base.h new file mode 100644 index 000000000..c755a6f9d --- /dev/null +++ b/trunk/Examples/python/import_template/base.h @@ -0,0 +1,18 @@ +#include <stdio.h> + +template<class T> class Base { + public: + Base() { }; + virtual ~Base() { }; + virtual void A() { + printf("I'm Base::A\n"); + } + void B() { + printf("I'm Base::B\n"); + } + virtual Base<T> *toBase() { + return static_cast<Base<T> *>(this); + } +}; + + diff --git a/trunk/Examples/python/import_template/base.i b/trunk/Examples/python/import_template/base.i new file mode 100644 index 000000000..a6da06339 --- /dev/null +++ b/trunk/Examples/python/import_template/base.i @@ -0,0 +1,7 @@ +%module base +%{ +#include "base.h" +%} + +%include base.h +%template(intBase) Base<int>; diff --git a/trunk/Examples/python/import_template/foo.h b/trunk/Examples/python/import_template/foo.h new file mode 100644 index 000000000..3df13d20d --- /dev/null +++ b/trunk/Examples/python/import_template/foo.h @@ -0,0 +1,21 @@ +#include "base.h" + +template<class T> class Foo : public Base<T> { + public: + Foo() { } + ~Foo() { } + virtual void A() { + printf("I'm Foo::A\n"); + } + void B() { + printf("I'm Foo::B\n"); + } + virtual Base<T> *toBase() { + return static_cast<Base<T> *>(this); + } + static Foo<T> *fromBase(Base<T> *b) { + return dynamic_cast<Foo<T> *>(b); + } +}; + + diff --git a/trunk/Examples/python/import_template/foo.i b/trunk/Examples/python/import_template/foo.i new file mode 100644 index 000000000..e271672cd --- /dev/null +++ b/trunk/Examples/python/import_template/foo.i @@ -0,0 +1,10 @@ +%module foo +%{ +#include "foo.h" +%} + +%import base.i +%include "foo.h" + +%template(intFoo) Foo<int>; + diff --git a/trunk/Examples/python/import_template/runme.py b/trunk/Examples/python/import_template/runme.py new file mode 100644 index 000000000..0d5aded14 --- /dev/null +++ b/trunk/Examples/python/import_template/runme.py @@ -0,0 +1,111 @@ +# file: runme.py +# Test various properties of classes defined in separate modules + +print "Testing the %import directive with templates" +import base +import foo +import bar +import spam + +# Create some objects + +print "Creating some objects" + +a = base.intBase() +b = foo.intFoo() +c = bar.intBar() +d = spam.intSpam() + +# Try calling some methods +print "Testing some methods" +print "", +print "Should see 'Base::A' ---> ", +a.A() +print "Should see 'Base::B' ---> ", +a.B() + +print "Should see 'Foo::A' ---> ", +b.A() +print "Should see 'Foo::B' ---> ", +b.B() + +print "Should see 'Bar::A' ---> ", +c.A() +print "Should see 'Bar::B' ---> ", +c.B() + +print "Should see 'Spam::A' ---> ", +d.A() +print "Should see 'Spam::B' ---> ", +d.B() + +# Try some casts + +print "\nTesting some casts\n" +print "", + +x = a.toBase() +print "Should see 'Base::A' ---> ", +x.A() +print "Should see 'Base::B' ---> ", +x.B() + +x = b.toBase() +print "Should see 'Foo::A' ---> ", +x.A() + +print "Should see 'Base::B' ---> ", +x.B() + +x = c.toBase() +print "Should see 'Bar::A' ---> ", +x.A() + +print "Should see 'Base::B' ---> ", +x.B() + +x = d.toBase() +print "Should see 'Spam::A' ---> ", +x.A() + +print "Should see 'Base::B' ---> ", +x.B() + +x = d.toBar() +print "Should see 'Bar::B' ---> ", +x.B() + +print "\nTesting some dynamic casts\n" +x = d.toBase() + +print " Spam -> Base -> Foo : ", +y = foo.intFoo_fromBase(x) +if y: + print "bad swig" +else: + print "good swig" + +print " Spam -> Base -> Bar : ", +y = bar.intBar_fromBase(x) +if y: + print "good swig" +else: + print "bad swig" + +print " Spam -> Base -> Spam : ", +y = spam.intSpam_fromBase(x) +if y: + print "good swig" +else: + print "bad swig" + +print " Foo -> Spam : ", +y = spam.intSpam_fromBase(b) +if y: + print "bad swig" +else: + print "good swig" + + + + diff --git a/trunk/Examples/python/import_template/spam.h b/trunk/Examples/python/import_template/spam.h new file mode 100644 index 000000000..c72f49a32 --- /dev/null +++ b/trunk/Examples/python/import_template/spam.h @@ -0,0 +1,24 @@ +#include "bar.h" + +template<class T> class Spam : public Bar<T> { + public: + Spam() { } + ~Spam() { } + virtual void A() { + printf("I'm Spam::A\n"); + } + void B() { + printf("I'm Spam::B\n"); + } + virtual Base<T> *toBase() { + return static_cast<Base<T> *>(this); + } + virtual Bar<T> *toBar() { + return static_cast<Bar<T> *>(this); + } + static Spam<T> *fromBase(Base<T> *b) { + return dynamic_cast<Spam<T> *>(b); + } +}; + + diff --git a/trunk/Examples/python/import_template/spam.i b/trunk/Examples/python/import_template/spam.i new file mode 100644 index 000000000..dd94b0350 --- /dev/null +++ b/trunk/Examples/python/import_template/spam.i @@ -0,0 +1,10 @@ +%module spam +%{ +#include "spam.h" +%} + +%import bar.i +%include "spam.h" + +%template(intSpam) Spam<int>; + diff --git a/trunk/Examples/python/index.html b/trunk/Examples/python/index.html new file mode 100644 index 000000000..8443a85e1 --- /dev/null +++ b/trunk/Examples/python/index.html @@ -0,0 +1,112 @@ +<html> +<head> +<title>SWIG:Examples:python</title> +</head> + +<body bgcolor="#ffffff"> +<H1>SWIG Python Examples</H1> + +<p> +The following examples illustrate the use of SWIG with Python. + +<ul> +<li><a href="simple/index.html">simple</a>. A minimal example showing how SWIG can +be used to wrap a C function, a global variable, and a constant. +<li><a href="constants/index.html">constants</a>. This shows how preprocessor macros and +certain C declarations are turned into constants. +<li><a href="variables/index.html">variables</a>. An example showing how to access C global variables from Python. +<li><a href="value/index.html">value</a>. How to pass and return structures by value. +<li><a href="class/index.html">class</a>. Wrapping a simple C++ class. +<li><a href="reference/index.html">reference</a>. C++ references. +<li><a href="pointer/index.html">pointer</a>. Simple pointer handling. +<li><a href="funcptr/index.html">funcptr</a>. Pointers to functions. +</ul> + +<h2>Compilation Issues</h2> + +<ul> +<li>To create a Python extension, SWIG is run with the following options: + +<blockquote> +<pre> +% swig -python interface.i +</pre> +</blockquote> + +<li> +Please see the <a href="../../Doc/Manual/Windows.html">Windows</a> page in the main manual for information on using the examples on Windows. <p> +</li> + +<li>On Unix the compilation of examples is done using the file <tt>Example/Makefile</tt>. This +makefile performs a manual module compilation which is platform specific. Typically, +the steps look like this (Linux): + +<blockquote> +<pre> +% swig -python interface.i +% gcc -fpic -c interface_wrap.c -I/usr/local/include/python1.5 +% gcc -shared interface_wrap.o $(OBJS) -o interfacemodule.so +% python +Python 1.5.2 (#3, Oct 9 1999, 22:09:34) [GCC 2.95.1 19990816 (release)] on linux2 +Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam +>>> import interface +>>> interface.blah(...) +... +</pre> +</blockquote> + +<li>The politically "correct" way to compile a Python extension is to follow the steps +described at <a href="http://www.python.org/doc/current/ext/building-on-unix.html">www.python.org</a> +or in the most excellent (and shamelessly plugged) <a href="http://islab.cs.uchicago.edu/python">Python Essential Reference</a>: + +<p> +<ol> +<li>Create a file called <tt>Setup</tt> that looks like the following where $(SRCS) is filled +in with any other source files you need to build the extension: + +<blockquote> +<pre> +*shared* +interface interface_wrap.c $(SRCS) +</pre> +</blockquote> +<li>Copy the file <tt>Makefile.pre.in</tt> from the Python distribution. Usually it's located +in the directory <tt>/usr/local/lib/python1.5/config</tt> on a Unix machine. + +<p> +<li>Type the following to build the extension: + +<blockquote> +<pre> +% make -f Makefile.pre.in boot +% make +</pre> +</blockquote> +<li> And that's it. If you are preparing an extension for distribution, you may want +to look at the <a href="http://www.python.org/sigs/distutils-sig/">distutils</a>. +</ol> +</ul> + +<h2>Compatibility</h2> + +The examples have been extensively tested on the following platforms: + +<ul> +<li>Linux +<li>Solaris +</ul> + +All of the examples were last tested with the following configuration (9/1/2000): + +<ul> +<li>Sparc Solaris 2.8. +<li>gcc-2.95.2 +<li>Python 1.6b1. +</ul> + +Your mileage may vary. If you experience a problem, please let us know by +contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>. +</body> +</html> + + diff --git a/trunk/Examples/python/java/Example.java b/trunk/Examples/python/java/Example.java new file mode 100644 index 000000000..91ddb1ac5 --- /dev/null +++ b/trunk/Examples/python/java/Example.java @@ -0,0 +1,29 @@ +public class Example { + public int mPublicInt; + + public Example() { + mPublicInt = 0; + } + + public Example(int IntVal) { + mPublicInt = IntVal; + } + + + public int Add(int a, int b) { + return (a+b); + } + + public float Add(float a, float b) { + return (a+b); + } + + public String Add(String a, String b) { + return (a+b); + } + + public Example Add(Example a, Example b) { + return new Example(a.mPublicInt + b.mPublicInt); + } +} + diff --git a/trunk/Examples/python/java/Makefile b/trunk/Examples/python/java/Makefile new file mode 100644 index 000000000..326a4da94 --- /dev/null +++ b/trunk/Examples/python/java/Makefile @@ -0,0 +1,25 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: Example.class + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' CXX="gcj" \ + CXXSHARED="gcj -fpic -shared Example.class" DEFS='' LIBS="-lstdc++" python_cpp + + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + rm -f *.class Example.h + +check: all + + +Example.class: Example.java + gcj -fPIC -C -c -g Example.java + gcjh Example + diff --git a/trunk/Examples/python/java/example.i b/trunk/Examples/python/java/example.i new file mode 100644 index 000000000..13d5b5e70 --- /dev/null +++ b/trunk/Examples/python/java/example.i @@ -0,0 +1,9 @@ +%module example +%include <cni.i> + +%{ +#include "Example.h" +%} + + +%include Example.h diff --git a/trunk/Examples/python/java/runme.py b/trunk/Examples/python/java/runme.py new file mode 100644 index 000000000..0cec8a7cb --- /dev/null +++ b/trunk/Examples/python/java/runme.py @@ -0,0 +1,16 @@ +from example import * + +JvCreateJavaVM(None) +JvAttachCurrentThread(None, None) + +e1 = Example(1) +e2 = Example(2) + +print e1.Add(1,2) +print e1.Add(1.0,2.0) +e3 = e1.Add(e1,e2) +print e3.mPublicInt + +print e1.Add("1","2") + +JvDetachCurrentThread() diff --git a/trunk/Examples/python/libffi/Makefile b/trunk/Examples/python/libffi/Makefile new file mode 100644 index 000000000..fafb7de09 --- /dev/null +++ b/trunk/Examples/python/libffi/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' LIBS='-L/usr/local/lib -lffi' python + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/libffi/example.i b/trunk/Examples/python/libffi/example.i new file mode 100644 index 000000000..9a29ec04e --- /dev/null +++ b/trunk/Examples/python/libffi/example.i @@ -0,0 +1,176 @@ +/* File : example.i */ +%module example + +%{ +#include <unistd.h> +#include <ffi.h> +%} + +/* A wrapper for execlp() using libffi to handle an arbitrary + number of arguments */ + +%typemap(in) (...) { + char **argv; + int argc; + int i; + + argc = PyTuple_Size(varargs); + argv = (char **) malloc(sizeof(char *)*(argc+1)); + for (i = 0; i < argc; i++) { + PyObject *o = PyTuple_GetItem(varargs,i); + if (!PyString_Check(o)) { + PyErr_SetString(PyExc_ValueError,"Expected a string"); + return NULL; + } + argv[i] = PyString_AsString(o); + } + argv[i] = NULL; + $1 = (void *) argv; +} + +/* Rewrite the function call, using libffi */ +%feature("action") execlp { + int i, vc; + ffi_cif cif; + ffi_type **types; + void **values; + char **args; + + vc = PyTuple_Size(varargs); + types = (ffi_type **) malloc((vc+3)*sizeof(ffi_type *)); + values = (void **) malloc((vc+3)*sizeof(void *)); + args = (char **) arg3; + + /* Set up path parameter */ + types[0] = &ffi_type_pointer; + values[0] = &arg1; + + /* Set up first argument */ + types[1] = &ffi_type_pointer; + values[1] = &arg2; + + /* Set up rest of parameters */ + for (i = 0; i <= vc; i++) { + types[2+i] = &ffi_type_pointer; + values[2+i] = &args[i]; + } + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3, + &ffi_type_uint, types) == FFI_OK) { + ffi_call(&cif, (void (*)()) execlp, &result, values); + } else { + PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); + free(types); + free(values); + free(arg3); + return NULL; + } + free(types); + free(values); + free(arg3); +} + +int execlp(const char *path, const char *arg1, ...); + + +/* A wrapper for printf() using libffi */ + +%{ + typedef struct { + int type; + union { + int ivalue; + double dvalue; + void *pvalue; + } val; + } vtype; + enum { VT_INT, VT_DOUBLE, VT_POINTER }; + %} + +%typemap(in) (const char *fmt, ...) { + vtype *argv; + int argc; + int i; + + $1 = PyString_AsString($input); + + argc = PyTuple_Size(varargs); + argv = (vtype *) malloc(argc*sizeof(vtype)); + for (i = 0; i < argc; i++) { + PyObject *o = PyTuple_GetItem(varargs,i); + if (PyInt_Check(o)) { + argv[i].type = VT_INT; + argv[i].val.ivalue = PyInt_AsLong(o); + } else if (PyFloat_Check(o)) { + argv[i].type = VT_DOUBLE; + argv[i].val.dvalue = PyFloat_AsDouble(o); + } else if (PyString_Check(o)) { + argv[i].type = VT_POINTER; + argv[i].val.pvalue = (void *) PyString_AsString(o); + } else { + PyErr_SetString(PyExc_ValueError,"Unsupported argument type"); + free(argv); + return NULL; + } + } + + $2 = (void *) argv; +} + +/* Rewrite the function call, using libffi */ +%feature("action") printf { + int i, vc; + ffi_cif cif; + ffi_type **types; + void **values; + vtype *args; + + vc = PyTuple_Size(varargs); + types = (ffi_type **) malloc((vc+1)*sizeof(ffi_type *)); + values = (void **) malloc((vc+1)*sizeof(void *)); + args = (vtype *) arg2; + + /* Set up fmt parameter */ + types[0] = &ffi_type_pointer; + values[0] = &arg1; + + /* Set up rest of parameters */ + for (i = 0; i < vc; i++) { + switch(args[i].type) { + case VT_INT: + types[1+i] = &ffi_type_uint; + values[1+i] = &args[i].val.ivalue; + break; + case VT_DOUBLE: + types[1+i] = &ffi_type_double; + values[1+i] = &args[i].val.dvalue; + break; + case VT_POINTER: + types[1+i] = &ffi_type_pointer; + values[1+i] = &args[i].val.pvalue; + break; + default: + abort(); /* Whoa! We're seriously hosed */ + break; + } + } + if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1, + &ffi_type_uint, types) == FFI_OK) { + ffi_call(&cif, (void (*)()) printf, &result, values); + } else { + PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!"); + free(types); + free(values); + free(args); + return NULL; + } + free(types); + free(values); + free(args); +} + +int printf(const char *fmt, ...); + + + + + diff --git a/trunk/Examples/python/multimap/Makefile b/trunk/Examples/python/multimap/Makefile new file mode 100644 index 000000000..0f4a1e077 --- /dev/null +++ b/trunk/Examples/python/multimap/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-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:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/multimap/example.c b/trunk/Examples/python/multimap/example.c new file mode 100644 index 000000000..b8360fa8a --- /dev/null +++ b/trunk/Examples/python/multimap/example.c @@ -0,0 +1,53 @@ +/* File : example.c */ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +int gcdmain(int argc, char *argv[]) { + int x,y; + if (argc != 3) { + printf("usage: gcd x y\n"); + return -1; + } + x = atoi(argv[1]); + y = atoi(argv[2]); + printf("gcd(%d,%d) = %d\n", x,y,gcd(x,y)); + return 0; +} + +int count(char *bytes, int len, char c) { + int i; + int count = 0; + for (i = 0; i < len; i++) { + if (bytes[i] == c) count++; + } + return count; +} + +void capitalize(char *str, int len) { + int i; + for (i = 0; i < len; i++) { + str[i] = (char)toupper(str[i]); + } +} + +void circle(double x, double y) { + double a = x*x + y*y; + if (a > 1.0) { + printf("Bad points %g, %g\n", x,y); + } else { + printf("Good points %g, %g\n", x,y); + } +} diff --git a/trunk/Examples/python/multimap/example.dsp b/trunk/Examples/python/multimap/example.dsp new file mode 100644 index 000000000..32845e0e8 --- /dev/null +++ b/trunk/Examples/python/multimap/example.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=example - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "example.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "example - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /debug /machine:I386 /out:"_example.pyd" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "example - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /machine:I386 /out:"_example.pyd"
+
+!ENDIF
+
+# Begin Target
+
+# Name "example - Win32 Debug"
+# Name "example - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\example.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\example_wrap.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Source File
+
+SOURCE=.\example.i
+
+!IF "$(CFG)" == "example - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\example.i
+InputName=example
+
+"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -python $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "example - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\example.i
+InputName=example
+
+"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -python $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/trunk/Examples/python/multimap/example.i b/trunk/Examples/python/multimap/example.i new file mode 100644 index 000000000..f1c4d9990 --- /dev/null +++ b/trunk/Examples/python/multimap/example.i @@ -0,0 +1,121 @@ +/* File : example.i */ +%module example + +%{ +extern int gcd(int x, int y); +extern int gcdmain(int argc, char *argv[]); +extern int count(char *bytes, int len, char c); +extern void capitalize (char *str, int len); +extern void circle (double cx, double cy); +extern int squareCubed (int n, int *OUTPUT); +%} + +%include exception.i +%include typemaps.i + +extern int gcd(int x, int y); + +%typemap(in,fragment="t_output_helper") (int argc, char *argv[]) { + int i; + if (!PyList_Check($input)) { + SWIG_exception(SWIG_ValueError, "Expecting a list"); + } + $1 = PyList_Size($input); + if ($1 == 0) { + SWIG_exception(SWIG_ValueError, "List must contain at least 1 element"); + } + $2 = (char **) malloc(($1+1)*sizeof(char *)); + for (i = 0; i < $1; i++) { + PyObject *s = PyList_GetItem($input,i); +%#if PY_VERSION_HEX >= 0x03000000 + if (!PyUnicode_Check(s)) +%#else + if (!PyString_Check(s)) +%#endif + { + free($2); + SWIG_exception(SWIG_ValueError, "List items must be strings"); + } +%#if PY_VERSION_HEX >= 0x03000000 + { + int l; + $2[i] = PyUnicode_AsStringAndSize(s, &l); + } +%#else + $2[i] = PyString_AsString(s); +%#endif + + } + $2[i] = 0; +} + +extern int gcdmain(int argc, char *argv[]); + +%typemap(in) (char *bytes, int len) { + +%#if PY_VERSION_HEX >= 0x03000000 + if (!PyUnicode_Check($input)) { + PyErr_SetString(PyExc_ValueError,"Expected a string"); + return NULL; + } + $1 = PyUnicode_AsStringAndSize($input, &$2); +%#else + if (!PyString_Check($input)) { + PyErr_SetString(PyExc_ValueError,"Expected a string"); + return NULL; + } + $1 = PyString_AsString($input); + $2 = PyString_Size($input); +%#endif +} + +extern int count(char *bytes, int len, char c); + + +/* This example shows how to wrap a function that mutates a string */ + +/* Since str is modified, we make a copy of the Python object + so that we don't violate it's mutability */ + +%typemap(in) (char *str, int len) { +%#if PY_VERSION_HEX >= 0x03000000 + $2 = PyUnicode_GetSize($input); + $1 = (char *) malloc($2+1); + memmove($1,PyUnicode_AsString($input),$2); +%#else + $2 = PyString_Size($input); + $1 = (char *) malloc($2+1); + memmove($1,PyString_AsString($input),$2); +%#endif +} + +/* Return the mutated string as a new object. The t_output_helper + function takes an object and appends it to the output object + to create a tuple */ + +%typemap(argout) (char *str, int len) { + PyObject *o; +%#if PY_VERSION_HEX >= 0x03000000 + o = PyUnicode_FromStringAndSize($1,$2); +%#else + o = PyString_FromStringAndSize($1,$2); +%#endif + $result = t_output_helper($result,o); + free($1); +} + +extern void capitalize(char *str, int len); + +/* A multi-valued constraint. Force two arguments to lie + inside the unit circle */ + +%typemap(check) (double cx, double cy) { + double a = $1*$1 + $2*$2; + if (a > 1.0) { + SWIG_exception(SWIG_ValueError,"$1_name and $2_name must be in unit circle"); + } +} + +extern void circle(double cx, double cy); + + diff --git a/trunk/Examples/python/multimap/runme.py b/trunk/Examples/python/multimap/runme.py new file mode 100644 index 000000000..f996ab3ae --- /dev/null +++ b/trunk/Examples/python/multimap/runme.py @@ -0,0 +1,27 @@ +# file: runme.py + +import example + +# Call our gcd() function + +x = 42 +y = 105 +g = example.gcd(x,y) +print "The gcd of %d and %d is %d" % (x,y,g) + +# Call the gcdmain() function +example.gcdmain(["gcdmain","42","105"]) + +# Call the count function +print example.count("Hello World", "l") + +# Call the capitalize function + +print example.capitalize("hello world") + + + + + + + diff --git a/trunk/Examples/python/operator/Makefile b/trunk/Examples/python/operator/Makefile new file mode 100644 index 000000000..fe389757a --- /dev/null +++ b/trunk/Examples/python/operator/Makefile @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/operator/example.h b/trunk/Examples/python/operator/example.h new file mode 100644 index 000000000..4da6a2307 --- /dev/null +++ b/trunk/Examples/python/operator/example.h @@ -0,0 +1,36 @@ +/* File : example.h */ +#include <math.h> + +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; + + + + + diff --git a/trunk/Examples/python/operator/example.i b/trunk/Examples/python/operator/example.i new file mode 100644 index 000000000..e37e76b3e --- /dev/null +++ b/trunk/Examples/python/operator/example.i @@ -0,0 +1,28 @@ +/* File : example.i */ +%module example +#pragma SWIG nowarn=SWIGWARN_IGNORE_OPERATOR_EQ +%{ +#include "example.h" +%} + +/* This header file is a little tough to handle because it has overloaded + operators and constructors. We're going to try and deal with that here */ + +/* This turns the copy constructor in a function ComplexCopy() that can + be called */ + +%rename(ComplexCopy) Complex::Complex(Complex const &); + +/* Now grab the original header file */ +%include "example.h" + +/* An output method that turns a complex into a short string */ +%extend Complex { + char *__str__() { + static char temp[512]; + sprintf(temp,"(%g,%g)", $self->re(), $self->im()); + return temp; + } +}; + + diff --git a/trunk/Examples/python/operator/runme.py b/trunk/Examples/python/operator/runme.py new file mode 100644 index 000000000..3687a38de --- /dev/null +++ b/trunk/Examples/python/operator/runme.py @@ -0,0 +1,21 @@ +# Operator overloading example +import example + +a = example.Complex(2,3) +b = example.Complex(-5,10) + +print "a =",a +print "b =",b + +c = a + b +print "c =",c +print "a*b =",a*b +print "a-c =",a-c + +e = example.ComplexCopy(a-c) +print "e =",e + +# Big expression +f = ((a+b)*(c+b*e)) + (-a) +print "f =",f + diff --git a/trunk/Examples/python/pointer/Makefile b/trunk/Examples/python/pointer/Makefile new file mode 100644 index 000000000..0f4a1e077 --- /dev/null +++ b/trunk/Examples/python/pointer/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-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:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/pointer/example.c b/trunk/Examples/python/pointer/example.c new file mode 100644 index 000000000..b877d9a5b --- /dev/null +++ b/trunk/Examples/python/pointer/example.c @@ -0,0 +1,16 @@ +/* File : example.c */ + +void add(int *x, int *y, int *result) { + *result = *x + *y; +} + +void sub(int *x, int *y, int *result) { + *result = *x - *y; +} + +int divide(int n, int d, int *r) { + int q; + q = n/d; + *r = n - q*d; + return q; +} diff --git a/trunk/Examples/python/pointer/example.i b/trunk/Examples/python/pointer/example.i new file mode 100644 index 000000000..a8ac79499 --- /dev/null +++ b/trunk/Examples/python/pointer/example.i @@ -0,0 +1,30 @@ +/* File : example.i */ +%module example + +%{ +extern void add(int *, int *, int *); +extern void sub(int *, int *, int *); +extern int divide(int, int, int *); +%} + +/* This example illustrates a couple of different techniques + for manipulating C pointers */ + +/* First we'll use the pointer library */ +extern void add(int *x, int *y, int *result); +%include cpointer.i +%pointer_functions(int, intp); + +/* Next we'll use some typemaps */ + +%include typemaps.i +extern void sub(int *INPUT, int *INPUT, int *OUTPUT); + +/* Next we'll use typemaps and the %apply directive */ + +%apply int *OUTPUT { int *r }; +extern int divide(int n, int d, int *r); + + + + diff --git a/trunk/Examples/python/pointer/index.html b/trunk/Examples/python/pointer/index.html new file mode 100644 index 000000000..b99c8fe4c --- /dev/null +++ b/trunk/Examples/python/pointer/index.html @@ -0,0 +1,171 @@ +<html> +<head> +<title>SWIG:Examples:python:pointer</title> +</head> + +<body bgcolor="#ffffff"> + +<tt>SWIG/Examples/python/pointer/</tt> +<hr> + +<H2>Simple Pointer Handling</H2> + +<p> +This example illustrates a couple of techniques for handling +simple pointers in SWIG. The prototypical example is a C function +that operates on pointers such as this: + +<blockquote> +<pre> +void add(int *x, int *y, int *r) { + *r = *x + *y; +} +</pre> +</blockquote> + +By default, SWIG wraps this function exactly as specified and creates +an interface that expects pointer objects for arguments. The only +problem is how does one go about creating these objects from a script? + +<h2>Possible Solutions</h2> + +<ul> +<li>Write some helper functions to explicitly create objects. For +example: + +<blockquote> +<pre> +int *new_int(int ivalue) { + int *i = (int *) malloc(sizeof(ivalue)); + *i = ivalue; + return i; +} +int get_int(int *i) { + return *i; +} + +void delete_int(int *i) { + free(i); +} +</pre> +</blockquote> + +Now, in a script you would do this: + +<blockquote> +<pre> +a = new_int(37) +b = new_int(42) +c = new_int(0) +add(a,b,c) +r = get_int(c); +print "Result =",r +delete_int(a) +delete_int(b) +delete_int(c) +</pre> +</blockquote> + +<p> +<li>Use the SWIG pointer library. For example, in the interface file +you would do this: + +<blockquote> +<pre> +%include "pointer.i" +</pre> +</blockquote? + +and in a script you would do this: + +<blockquote> +<pre> +a = ptrcreate("int",37) +b = ptrcreate("int",42) +c = ptrcreate("int") +add(a,b,c) +r = ptrvalue(c) +print "Result =",r +ptrfree(a) +ptrfree(b) +ptrfree(c) +</pre> +</blockquote> + +The advantage to using the pointer library is that it unifies some of the helper +functions behind a common set of names. For example, the same set of functions work +with int, double, float, and other fundamental types. + +<p> +<li>Use the SWIG typemap library. This library allows you to completely +change the way arguments are processed by SWIG. For example: + +<blockquote> +<pre> +%include "typemaps.i" +void add(int *INPUT, int *INPUT, int *OUTPUT); +</pre> +</blockquote> + +And in a script: + +<blockquote> +<pre> +r = add(37,42) +print "Result =",r +</pre> +</blockquote> +Needless to say, this is substantially easier. + +<p> +<li>A final alternative is to use the typemaps library in combination +with the %apply directive. This allows you to change the names of parameters +that behave as input or output parameters. For example: + +<blockquote> +<pre> +%include "typemaps.i" +%apply int *INPUT {int *x, int *y}; +%apply int *OUTPUT {int *r}; + +void add(int *x, int *y, int *r); +void sub(int *x, int *y, int *r); +void mul(int *x, int *y, int *r); +... etc ... +</pre> +</blockquote> + +</ul> + +<h2>Example</h2> + +The following example illustrates the use of these features for pointer +extraction. + +<ul> +<li> <a href="example.c">example.c</a> (C Source) +<li> <a href="example.i">example.i</a> (SWIG interface) +<li> <a href="example.py">example.py</a> (Python Script) +</ul> + +<h2>Notes</h2> + +<ul> +<li>Since pointers are used for so many different things (arrays, output values, +etc...) the complexity of pointer handling can be as complicated as you want to +make it. + +<p> +<li>More documentation on the typemaps.i and pointer.i library files can be +found in the SWIG user manual. The files also contain documentation. + +<p> +<li>The pointer.i library is designed primarily for convenience. If you +are concerned about performance, you probably want to use a different +approach. + +</ul> + +<hr> +</body> +</html> diff --git a/trunk/Examples/python/pointer/runme.py b/trunk/Examples/python/pointer/runme.py new file mode 100644 index 000000000..e38a306c1 --- /dev/null +++ b/trunk/Examples/python/pointer/runme.py @@ -0,0 +1,44 @@ +# file: runme.py + +import example; + +# First create some objects using the pointer library. +print "Testing the pointer library"; +a = example.new_intp(); +b = example.new_intp(); +c = example.new_intp(); +example.intp_assign(a,37); +example.intp_assign(b,42); + +print " a =",a +print " b =",b +print " c =",c + +# Call the add() function with some pointers +example.add(a,b,c) + +# Now get the result +r = example.intp_value(c) +print " 37 + 42 =",r + +# Clean up the pointers +example.delete_intp(a) +example.delete_intp(b) +example.delete_intp(c) + +# Now try the typemap library +# This should be much easier. Now how it is no longer +# necessary to manufacture pointers. + +print "Trying the typemap library"; +r = example.sub(37,42) +print " 37 - 42 =",r + +# Now try the version with multiple return values + +print "Testing multiple return values"; +q,r = example.divide(42,37) +print " 42/37 = %d remainder %d" % (q,r) + + + diff --git a/trunk/Examples/python/reference/Makefile b/trunk/Examples/python/reference/Makefile new file mode 100644 index 000000000..74625b992 --- /dev/null +++ b/trunk/Examples/python/reference/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/reference/example.cxx b/trunk/Examples/python/reference/example.cxx new file mode 100644 index 000000000..8a513bf49 --- /dev/null +++ b/trunk/Examples/python/reference/example.cxx @@ -0,0 +1,46 @@ +/* File : example.cxx */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include "example.h" +#include <stdio.h> +#include <stdlib.h> + +Vector operator+(const Vector &a, const Vector &b) { + Vector r; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + return r; +} + +char *Vector::print() { + static char temp[512]; + sprintf(temp,"Vector %p (%g,%g,%g)", this, x,y,z); + return temp; +} + +VectorArray::VectorArray(int size) { + items = new Vector[size]; + maxsize = size; +} + +VectorArray::~VectorArray() { + delete [] items; +} + +Vector &VectorArray::operator[](int index) { + if ((index < 0) || (index >= maxsize)) { + printf("Panic! Array index out of bounds.\n"); + exit(1); + } + return items[index]; +} + +int VectorArray::size() { + return maxsize; +} + diff --git a/trunk/Examples/python/reference/example.h b/trunk/Examples/python/reference/example.h new file mode 100644 index 000000000..4915adb1b --- /dev/null +++ b/trunk/Examples/python/reference/example.h @@ -0,0 +1,26 @@ +/* File : example.h */ + +class Vector { +private: + double x,y,z; +public: + Vector() : x(0), y(0), z(0) { }; + Vector(double x, double y, double z) : x(x), y(y), z(z) { }; + friend Vector operator+(const Vector &a, const Vector &b); + char *print(); +}; + +class VectorArray { +private: + Vector *items; + int maxsize; +public: + VectorArray(int maxsize); + ~VectorArray(); + Vector &operator[](int); + int size(); +}; + + + + diff --git a/trunk/Examples/python/reference/example.i b/trunk/Examples/python/reference/example.i new file mode 100644 index 000000000..8c95b3213 --- /dev/null +++ b/trunk/Examples/python/reference/example.i @@ -0,0 +1,48 @@ +/* File : example.i */ + +/* This file has a few "typical" uses of C++ references. */ + +%module example + +%{ +#include "example.h" +%} + +%rename(cprint) print; + +class Vector { +public: + Vector(double x, double y, double z); + ~Vector(); + char *print(); +}; + +/* This helper function calls an overloaded operator */ +%inline %{ +Vector addv(Vector &a, Vector &b) { + return a+b; +} +%} + +/* Wrapper around an array of vectors class */ + +class VectorArray { +public: + VectorArray(int maxsize); + ~VectorArray(); + int size(); + + /* This wrapper provides an alternative to the [] operator */ + %extend { + Vector &get(int index) { + return (*$self)[index]; + } + void set(int index, Vector &a) { + (*$self)[index] = a; + } + } +}; + + + + diff --git a/trunk/Examples/python/reference/index.html b/trunk/Examples/python/reference/index.html new file mode 100644 index 000000000..25d40299e --- /dev/null +++ b/trunk/Examples/python/reference/index.html @@ -0,0 +1,147 @@ +<html> +<head> +<title>SWIG:Examples:python:reference</title> +</head> + +<body bgcolor="#ffffff"> + + +<tt>SWIG/Examples/python/reference/</tt> +<hr> + +<H2>C++ Reference Handling</H2> + +<p> +This example tests SWIG's handling of C++ references. Since C++ +references are closely related to pointers (as both refer to a +location in memory), SWIG simply collapses all references into +pointers when creating wrappers. + +<h2>Some examples</h2> + +References are most commonly used as function parameter. For example, +you might have an operator like this: + +<blockquote> +<pre> +Vector operator+(const Vector &a, const Vector &b) { + Vector result; + result.x = a.x + b.x; + result.y = a.y + b.y; + result.z = a.z + b.z; + return result; +} +</pre> +</blockquote> + +or a function: + +<blockquote> +<pre> +Vector addv(const Vector &a, const Vector &b) { + Vector result; + result.x = a.x + b.x; + result.y = a.y + b.y; + result.z = a.z + b.z; + return result; +} +</pre> +</blockquote> + +In these cases, SWIG transforms everything into a pointer and creates a wrapper +that looks like this: + +<blockquote> +<pre> +Vector wrap_addv(Vector *a, Vector *b) { + return addv(*a,*b); +} +</pre> +</blockquote> + +Occasionally, a reference is used as a return value of a function +when the return result is to be used as an lvalue in an expression. +The prototypical example is an operator like this: + +<blockquote> +<pre> +Vector &operator[](int index); +</pre> +</blockquote> + +or a method: + +<blockquote> +<pre> +Vector &get(int index); +</pre> +</blockquote> + +For functions returning references, a wrapper like this is created: + +<blockquote> +<pre> +Vector *wrap_Object_get(Object *self, int index) { + Vector &result = self->get(index); + return &result; +} +</pre> +</blockquote> + +The following <a href="example.h">header file</a> contains some class +definitions with some operators and use of references. + +<h2>SWIG Interface</h2> + +SWIG does NOT support overloaded operators so it can not directly build +an interface to the classes in the above file. However, a number of workarounds +can be made. For example, an overloaded operator can be stuck behind a function +call such as the <tt>addv()</tt> function above. Array access can be handled +with a pair of set/get functions like this: + +<blockquote> +<pre> +class VectorArray { +public: + ... + %addmethods { + Vector &get(int index) { + return (*self)[index]; + } + void set(int index, Vector &a) { + (*self)[index] = a; + } + } + ... +} +</pre> +</blockquote> + +Click <a href="example.i">here</a> to see a SWIG interface file with these additions. + +<h2>Sample Python script</h2> + +Click <a href="example.py">here</a> to see a script that manipulates some C++ references. + +<h2>Notes:</h2> + +<ul> +<li>C++ references primarily provide notational convenience for C++ +source code. However, Python only supports the 'x.a' +notation so it doesn't much matter. + +<p> +<li>When a program returns a reference, a pointer is returned. +Unlike return by value, memory is not allocated to hold the +return result. + +<p> +<li>SWIG has particular trouble handling various combinations of references +and pointers. This is side effect of an old parsing scheme and +type representation that will be replaced in future versions. + +</ul> + +<hr> +</body> +</html> diff --git a/trunk/Examples/python/reference/runme.py b/trunk/Examples/python/reference/runme.py new file mode 100644 index 000000000..a1f53368e --- /dev/null +++ b/trunk/Examples/python/reference/runme.py @@ -0,0 +1,63 @@ +# file: runme.py + +# This file illustrates the manipulation of C++ references in Python + +import example + +# ----- Object creation ----- + +print "Creating some objects:" +a = example.Vector(3,4,5) +b = example.Vector(10,11,12) + +print " Created",a.cprint() +print " Created",b.cprint() + +# ----- Call an overloaded operator ----- + +# This calls the wrapper we placed around +# +# operator+(const Vector &a, const Vector &) +# +# It returns a new allocated object. + +print "Adding a+b" +c = example.addv(a,b) +print " a+b =", c.cprint() + +# Note: Unless we free the result, a memory leak will occur +del c + +# ----- Create a vector array ----- + +# Note: Using the high-level interface here +print "Creating an array of vectors" +va = example.VectorArray(10) +print " va = ",va + +# ----- Set some values in the array ----- + +# These operators copy the value of $a and $b to the vector array +va.set(0,a) +va.set(1,b) + +va.set(2,example.addv(a,b)) + +# Get some values from the array + +print "Getting some array values" +for i in range(0,5): + print " va(%d) = %s" % (i, va.get(i).cprint()) + +# Watch under resource meter to check on this +print "Making sure we don't leak memory." +for i in xrange(0,1000000): + c = va.get(i % 10) + +# ----- Clean up ----- +print "Cleaning up" + +del va +del a +del b + diff --git a/trunk/Examples/python/simple/Makefile b/trunk/Examples/python/simple/Makefile new file mode 100644 index 000000000..0f4a1e077 --- /dev/null +++ b/trunk/Examples/python/simple/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-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:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/simple/example.c b/trunk/Examples/python/simple/example.c new file mode 100644 index 000000000..1c2af789c --- /dev/null +++ b/trunk/Examples/python/simple/example.c @@ -0,0 +1,18 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + + diff --git a/trunk/Examples/python/simple/example.dsp b/trunk/Examples/python/simple/example.dsp new file mode 100644 index 000000000..32845e0e8 --- /dev/null +++ b/trunk/Examples/python/simple/example.dsp @@ -0,0 +1,148 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=example - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "example.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "example - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "_DEBUG"
+# ADD RSC /l 0x809 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /debug /machine:I386 /out:"_example.pyd" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "example - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c
+# ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x809 /d "NDEBUG"
+# ADD RSC /l 0x809 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /dll /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib "$(PYTHON_LIB)" /nologo /dll /machine:I386 /out:"_example.pyd"
+
+!ENDIF
+
+# Begin Target
+
+# Name "example - Win32 Debug"
+# Name "example - Win32 Release"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\example.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\example_wrap.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Source File
+
+SOURCE=.\example.i
+
+!IF "$(CFG)" == "example - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\example.i
+InputName=example
+
+"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -python $(InputPath)
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "example - Win32 Release"
+
+# Begin Custom Build
+InputPath=.\example.i
+InputName=example
+
+"$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ echo In order to function correctly, please ensure the following environment variables are correctly set:
+ echo PYTHON_INCLUDE: %PYTHON_INCLUDE%
+ echo PYTHON_LIB: %PYTHON_LIB%
+ echo on
+ ..\..\..\swig.exe -python $(InputPath)
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/trunk/Examples/python/simple/example.i b/trunk/Examples/python/simple/example.i new file mode 100644 index 000000000..24093b9bf --- /dev/null +++ b/trunk/Examples/python/simple/example.i @@ -0,0 +1,7 @@ +/* File : example.i */ +%module example + +%inline %{ +extern int gcd(int x, int y); +extern double Foo; +%} diff --git a/trunk/Examples/python/simple/index.html b/trunk/Examples/python/simple/index.html new file mode 100644 index 000000000..dace471a3 --- /dev/null +++ b/trunk/Examples/python/simple/index.html @@ -0,0 +1,97 @@ +<html> +<head> +<title>SWIG:Examples:python:simple</title> +</head> + +<body bgcolor="#ffffff"> + + +<tt>SWIG/Examples/python/simple/</tt> +<hr> + +<H2>Simple Python Example</H2> + +<p> +This example illustrates how you can hook Python to a very simple C program containing +a function and a global variable. + +<h2>The C Code</h2> + +Suppose you have the following C code: + +<blockquote> +<pre> +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} +</pre> +</blockquote> + +<h2>The SWIG interface</h2> + +Here is a simple SWIG interface file: + +<blockquote> +<pre> +/* File: example.i */ +%module example + +extern int gcd(int x, int y); +extern double Foo; +</pre> +</blockquote> + +<h2>Compilation</h2> + +<ol> +<li><tt>swig -python <a href="example.i">example.i</a></tt> +<p> +<li>Compile <tt><a href="example_wrap.c">example_wrap.c</a></tt> and <tt><a href="example.c">example.c</a></tt> +to create the extension <tt>examplemodule.so</tt>. +</ol> + +<h2>Using the extension</h2> + +Click <a href="example.py">here</a> to see a script that calls our C functions from Python. + +<h2>Key points</h2> + +<ul> +<li>Use the <tt>import</tt> statement to load your extension module from Python. For example: +<blockquote> +<pre> +import example +</pre> +</blockquote> + +<li>C functions work just like Python functions. For example: +<blockquote> +<pre> +g = example.gcd(42,105) +</pre> +</blockquote> + +<li>C global variables are accessed through a special variable called 'cvar'. For example: +<blockquote> +<pre> +a = example.cvar.Foo +</pre> +</blockquote> +</ul> + +<hr> +</body> +</html> diff --git a/trunk/Examples/python/simple/runme.py b/trunk/Examples/python/simple/runme.py new file mode 100644 index 000000000..d484ae916 --- /dev/null +++ b/trunk/Examples/python/simple/runme.py @@ -0,0 +1,30 @@ +# file: runme.py + +import example + +# Call our gcd() function + +x = 42 +y = 105 +g = example.gcd(x,y) +print "The gcd of %d and %d is %d" % (x,y,g) + +# Manipulate the Foo global variable + +# Output its current value +print "Foo = ", example.cvar.Foo + +# Change its value +example.cvar.Foo = 3.1415926 + +# See if the change took effect +print "Foo = ", example.cvar.Foo + + + + + + + + + diff --git a/trunk/Examples/python/smartptr/Makefile b/trunk/Examples/python/smartptr/Makefile new file mode 100644 index 000000000..f73802a6b --- /dev/null +++ b/trunk/Examples/python/smartptr/Makefile @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/smartptr/example.cxx b/trunk/Examples/python/smartptr/example.cxx new file mode 100644 index 000000000..92a3add45 --- /dev/null +++ b/trunk/Examples/python/smartptr/example.cxx @@ -0,0 +1,31 @@ +/* File : example.c */ + +#include "example.h" +#include <math.h> +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area() { + return M_PI*radius*radius; +} + +double Circle::perimeter() { + return 2*M_PI*radius; +} + +double Square::area() { + return width*width; +} + +double Square::perimeter() { + return 4*width; +} diff --git a/trunk/Examples/python/smartptr/example.h b/trunk/Examples/python/smartptr/example.h new file mode 100644 index 000000000..c0f9b1d57 --- /dev/null +++ b/trunk/Examples/python/smartptr/example.h @@ -0,0 +1,39 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area() = 0; + virtual double perimeter() = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(); + virtual double perimeter(); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(); + virtual double perimeter(); +}; + + + + + diff --git a/trunk/Examples/python/smartptr/example.i b/trunk/Examples/python/smartptr/example.i new file mode 100644 index 000000000..83da4f144 --- /dev/null +++ b/trunk/Examples/python/smartptr/example.i @@ -0,0 +1,20 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +#include "smartptr.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Grab smart pointer template */ + +%include "smartptr.h" + +/* Instantiate smart-pointers */ + +%template(ShapePtr) SmartPtr<Shape>; + + diff --git a/trunk/Examples/python/smartptr/runme.py b/trunk/Examples/python/smartptr/runme.py new file mode 100644 index 000000000..5ea1fb947 --- /dev/null +++ b/trunk/Examples/python/smartptr/runme.py @@ -0,0 +1,55 @@ +# file: runme.py + +# This file illustrates the proxy class C++ interface generated +# by SWIG. + +import example + +# ----- Object creation ----- + +print "Creating some objects:" +cc = example.Circle(10) +c = example.ShapePtr(cc) +print " Created circle", c +ss = example.Square(10) +s = example.ShapePtr(ss) +print " Created square", s + +# ----- Access a static member ----- + +print "\nA total of", example.cvar.Shape_nshapes,"shapes were created" + +# ----- Member data access ----- + +# Set the location of the object + +c.x = 20 +c.y = 30 + +s.x = -10 +s.y = 5 + +print "\nHere is their current position:" +print " Circle = (%f, %f)" % (c.x,c.y) +print " Square = (%f, %f)" % (s.x,s.y) + +# ----- Call some methods ----- + +print "\nHere are some properties of the shapes:" +for o in [c,s]: + print " ", o + print " area = ", o.area() + print " perimeter = ", o.perimeter() + +print "\nGuess I'll clean up now" + +# Note: this invokes the virtual destructor +del c +del s +del cc +del ss + +s = 3 +print example.cvar.Shape_nshapes,"shapes remain" +print "Goodbye" + diff --git a/trunk/Examples/python/smartptr/smartptr.h b/trunk/Examples/python/smartptr/smartptr.h new file mode 100644 index 000000000..2ffa1ca0e --- /dev/null +++ b/trunk/Examples/python/smartptr/smartptr.h @@ -0,0 +1,13 @@ +template<class T> class SmartPtr { +public: + SmartPtr(T *realPtr = 0) { pointee = realPtr; } + T *operator->() const { + return pointee; + } + T &operator*() const { + return *pointee; + } +private: + T *pointee; +}; + diff --git a/trunk/Examples/python/std_map/Makefile b/trunk/Examples/python/std_map/Makefile new file mode 100644 index 000000000..5d13da764 --- /dev/null +++ b/trunk/Examples/python/std_map/Makefile @@ -0,0 +1,25 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +run: + python runme.py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/std_map/example.h b/trunk/Examples/python/std_map/example.h new file mode 100644 index 000000000..79ccc6478 --- /dev/null +++ b/trunk/Examples/python/std_map/example.h @@ -0,0 +1,17 @@ +/* File : example.h */ + +#include <map> +#include <string> + +template<class Key, class Value> +std::map<Key,Value> half_map(const std::map<Key,Value>& v) { + typedef typename std::map<Key,Value>::const_iterator iter; + std::map<Key,Value> w; + for (iter i = v.begin(); i != v.end(); ++i) { + w[i->first] = (i->second)/2; + } + return w; +} + + + diff --git a/trunk/Examples/python/std_map/example.i b/trunk/Examples/python/std_map/example.i new file mode 100644 index 000000000..6a7af7108 --- /dev/null +++ b/trunk/Examples/python/std_map/example.i @@ -0,0 +1,27 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%include std_string.i +%include std_pair.i +%include std_map.i + +/* instantiate the required template specializations */ +namespace std { + /* remember to instantiate the key,value pair! */ + %template(DoubleMap) map<std::string,double>; + %template() map<std::string,int>; +} + +/* Let's just grab the original header file here */ +%include "example.h" + +%template(halfd) half_map<std::string,double>; +%template(halfi) half_map<std::string,int>; + + +%template() std::pair<swig::SwigPtr_PyObject, swig::SwigPtr_PyObject>; +%template(pymap) std::map<swig::SwigPtr_PyObject, swig::SwigPtr_PyObject>; diff --git a/trunk/Examples/python/std_map/runme.py b/trunk/Examples/python/std_map/runme.py new file mode 100644 index 000000000..b521c9c9c --- /dev/null +++ b/trunk/Examples/python/std_map/runme.py @@ -0,0 +1,82 @@ +# file: runme.py + +import example + +pmap = example.pymap() +pmap["hi"] = 1 +pmap["hello"] = 2 + + + + +dmap = {} +dmap["hello"] = 1.0 +dmap["hi"] = 2.0 + +print dmap.items() +print dmap.keys() +print dmap.values() + +print dmap +hmap = example.halfd(dmap) +dmap = hmap + +print dmap +for i in dmap.iterkeys(): + print "key", i + +for i in dmap.itervalues(): + print "val", i + +for k,v in dmap.iteritems(): + print "item", k,v + +dmap = example.DoubleMap() +dmap["hello"] = 1.0 +dmap["hi"] = 2.0 + +for i in dmap.iterkeys(): + print "key", i + +for i in dmap.itervalues(): + print "val", i + +for k,v in dmap.iteritems(): + print "item", k,v + + +print dmap.items() +print dmap.keys() +print dmap.values() + +hmap = example.halfd(dmap) +print hmap.keys() +print hmap.values() + + + +dmap = {} +dmap["hello"] = 2 +dmap["hi"] = 4 + +hmap = example.halfi(dmap) +print hmap +print hmap.keys() +print hmap.values() + + +dmap = hmap + +for i in dmap.iterkeys(): + print "key", i + +for i in dmap.itervalues(): + print "val", i + +for i in dmap.iteritems(): + print "item", i + +for k,v in dmap.iteritems(): + print "item", k,v + +print dmap diff --git a/trunk/Examples/python/std_vector/Makefile b/trunk/Examples/python/std_vector/Makefile new file mode 100644 index 000000000..ba5c79827 --- /dev/null +++ b/trunk/Examples/python/std_vector/Makefile @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/std_vector/example.h b/trunk/Examples/python/std_vector/example.h new file mode 100644 index 000000000..4f0dac70d --- /dev/null +++ b/trunk/Examples/python/std_vector/example.h @@ -0,0 +1,25 @@ +/* File : example.h */ + +#include <vector> +#include <algorithm> +#include <functional> +#include <numeric> + +double average(std::vector<int> v) { + return std::accumulate(v.begin(),v.end(),0.0)/v.size(); +} + +std::vector<double> half(const std::vector<double>& v) { + std::vector<double> w(v); + for (unsigned int i=0; i<w.size(); i++) + w[i] /= 2.0; + return w; +} + +void halve_in_place(std::vector<double>& v) { + // would you believe this is the same as the above? + std::transform(v.begin(),v.end(),v.begin(), + std::bind2nd(std::divides<double>(),2.0)); +} + + diff --git a/trunk/Examples/python/std_vector/example.i b/trunk/Examples/python/std_vector/example.i new file mode 100644 index 000000000..aa58b66e0 --- /dev/null +++ b/trunk/Examples/python/std_vector/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%include stl.i +/* instantiate the required template specializations */ +namespace std { + %template(IntVector) vector<int>; + %template(DoubleVector) vector<double>; +} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/trunk/Examples/python/std_vector/runme.py b/trunk/Examples/python/std_vector/runme.py new file mode 100644 index 000000000..d248ccbbb --- /dev/null +++ b/trunk/Examples/python/std_vector/runme.py @@ -0,0 +1,36 @@ +# file: runme.py + +import example + +# Call average with a Python list... + +print example.average([1,2,3,4]) + +# ... or a wrapped std::vector<int> + +v = example.IntVector(4) +for i in range(len(v)): + v[i] = i+1 +print example.average(v) + + +# half will return a Python list. +# Call it with a Python tuple... + +print example.half((1.0, 1.5, 2.0, 2.5, 3.0)) + +# ... or a wrapped std::vector<double> + +v = example.DoubleVector() +for i in [1,2,3,4]: + v.append(i) +print example.half(v) + + +# now halve a wrapped std::vector<double> in place + +example.halve_in_place(v) +for i in range(len(v)): + print v[i], "; ", +print + diff --git a/trunk/Examples/python/swigrun/Makefile b/trunk/Examples/python/swigrun/Makefile new file mode 100644 index 000000000..2142be5bb --- /dev/null +++ b/trunk/Examples/python/swigrun/Makefile @@ -0,0 +1,25 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(SWIG) -python -external-runtime + $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + rm -f swigpyrun.h + +check: all + + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/swigrun/example.cxx b/trunk/Examples/python/swigrun/example.cxx new file mode 100644 index 000000000..25906a559 --- /dev/null +++ b/trunk/Examples/python/swigrun/example.cxx @@ -0,0 +1,20 @@ +/* File : example.cxx */ + +#include <Python.h> +#include "swigpyrun.h" +#include "example.h" + + +Manager* convert_to_Manager(PyObject *py_obj) +{ + Manager* c_ptr; + swig_type_info *ty = SWIG_TypeQuery("Manager *"); + printf("manager ty %p \n", ty); + if (SWIG_ConvertPtr(py_obj, (void **) &c_ptr, ty, 0) == -1) { + c_ptr = 0; + } else { + Py_XINCREF(py_obj); + } + return c_ptr; +} + diff --git a/trunk/Examples/python/swigrun/example.h b/trunk/Examples/python/swigrun/example.h new file mode 100644 index 000000000..69e6fe4de --- /dev/null +++ b/trunk/Examples/python/swigrun/example.h @@ -0,0 +1,58 @@ +/* File : example.h */ + +#include <cstdio> +#include <iostream> +#include <vector> +#include <string> +#include <cmath> + +class Employee { +private: + std::string name; +public: + Employee(const char* n): name(n) {} + virtual std::string getTitle() { return getPosition() + " " + getName(); } + virtual std::string getName() { return name; } + virtual std::string getPosition() const { return "Employee"; } + virtual ~Employee() { printf("~Employee() @ %p\n", this); } +}; + + +class Manager: public Employee { +public: + Manager(const char* n): Employee(n) {} + virtual std::string getPosition() const { return "Manager"; } +}; + + +class EmployeeList { + std::vector<Employee*> list; +public: + EmployeeList() { + list.push_back(new Employee("Bob")); + list.push_back(new Employee("Jane")); + list.push_back(new Manager("Ted")); + } + void addEmployee(Employee *p) { + list.push_back(p); + std::cout << "New employee added. Current employees are:" << std::endl; + std::vector<Employee*>::iterator i; + for (i=list.begin(); i!=list.end(); i++) { + std::cout << " " << (*i)->getTitle() << std::endl; + } + } + const Employee *get_item(int i) { + return list[i]; + } + ~EmployeeList() { + std::vector<Employee*>::iterator i; + std::cout << "~EmployeeList, deleting " << list.size() << " employees." << std::endl; + for (i=list.begin(); i!=list.end(); i++) { + delete *i; + } + std::cout << "~EmployeeList empty." << std::endl; + } +}; + +Manager* convert_to_Manager(PyObject *obj); + diff --git a/trunk/Examples/python/swigrun/example.i b/trunk/Examples/python/swigrun/example.i new file mode 100644 index 000000000..c8ec32e09 --- /dev/null +++ b/trunk/Examples/python/swigrun/example.i @@ -0,0 +1,15 @@ +/* File : example.i */ +%module(directors="1") example +%{ +#include "example.h" +%} + +%include "std_vector.i" +%include "std_string.i" + +/* turn on director wrapping for Manager */ +%feature("director") Employee; +%feature("director") Manager; + +%include "example.h" + diff --git a/trunk/Examples/python/swigrun/runme.py b/trunk/Examples/python/swigrun/runme.py new file mode 100644 index 000000000..abcd96463 --- /dev/null +++ b/trunk/Examples/python/swigrun/runme.py @@ -0,0 +1,28 @@ +# file: runme.py + +# This file illustrates the cross language polymorphism using directors. + +import example + + +# CEO class, which overrides Employee::getPosition(). + +class CEO(example.Manager): + def __init__(self, name): + example.Manager.__init__(self, name) + def getPosition(self): + return "CEO" + def __del__(self): + print "CEO.__del__(),", self.getName() + # for proxy class extensions that are not "disowned" and + # define a __del__ method, it is very important to call the + # base class __del__. otherwise the c++ objects will never + # be deleted. + example.Manager.__del__(self) + + + + +e = CEO("Alice") +m = example.convert_to_Manager(e) +print m diff --git a/trunk/Examples/python/template/Makefile b/trunk/Examples/python/template/Makefile new file mode 100644 index 000000000..ba5c79827 --- /dev/null +++ b/trunk/Examples/python/template/Makefile @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/template/example.h b/trunk/Examples/python/template/example.h new file mode 100644 index 000000000..7401df650 --- /dev/null +++ b/trunk/Examples/python/template/example.h @@ -0,0 +1,32 @@ +/* File : example.h */ + +// Some template definitions + +template<class T> T max(T a, T b) { return a>b ? a : b; } + +template<class T> class vector { + T *v; + int sz; + public: + vector(int _sz) { + v = new T[_sz]; + sz = _sz; + } + T &get(int index) { + return v[index]; + } + void set(int index, T &val) { + v[index] = val; + } +#ifdef SWIG + %extend { + T getitem(int index) { + return $self->get(index); + } + void setitem(int index, T val) { + $self->set(index,val); + } + } +#endif +}; + diff --git a/trunk/Examples/python/template/example.i b/trunk/Examples/python/template/example.i new file mode 100644 index 000000000..8f94c4da1 --- /dev/null +++ b/trunk/Examples/python/template/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ + +%template(maxint) max<int>; +%template(maxdouble) max<double>; +%template(vecint) vector<int>; +%template(vecdouble) vector<double>; + diff --git a/trunk/Examples/python/template/runme.py b/trunk/Examples/python/template/runme.py new file mode 100644 index 000000000..05940bc67 --- /dev/null +++ b/trunk/Examples/python/template/runme.py @@ -0,0 +1,34 @@ +# file: runme.py + +import example + +# Call some templated functions +print example.maxint(3,7) +print example.maxdouble(3.14,2.18) + +# Create some class + +iv = example.vecint(100) +dv = example.vecdouble(1000) + +for i in range(0,100): + iv.setitem(i,2*i) + +for i in range(0,1000): + dv.setitem(i, 1.0/(i+1)) + +sum = 0 +for i in range(0,100): + sum = sum + iv.getitem(i) + +print sum + +sum = 0.0 +for i in range(0,1000): + sum = sum + dv.getitem(i) +print sum + +del iv +del dv + + diff --git a/trunk/Examples/python/varargs/Makefile b/trunk/Examples/python/varargs/Makefile new file mode 100644 index 000000000..1420b4e0b --- /dev/null +++ b/trunk/Examples/python/varargs/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = +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:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/varargs/example.i b/trunk/Examples/python/varargs/example.i new file mode 100644 index 000000000..6cb88f5f4 --- /dev/null +++ b/trunk/Examples/python/varargs/example.i @@ -0,0 +1,65 @@ +/* File : example.i */ +%module example + +%{ +#include <stdarg.h> +%} + +/* This example illustrates SWIG's handling of varargs functions. + By default, variable length arguments are simply ignored. This + is generally appropriate for wrapping I/O functions like printf. + You can simply format a string in the scripting language, and + pass it directly */ + +int printf(const char *fmt, ...); + +/* Since passing a format string might be dangerous. Here is a slightly + different way of wrapping a printf style function */ + +#if 1 +/* Replace ... with char *. */ +%varargs(char *) fprintf; + +/* Ignore the format string, but set it to %s */ +%typemap(in,numinputs=0) const char *fmt { + $1 = "%s"; +} +#else +/* An alternative approach using typemaps */ +%typemap(in) (const char *fmt, ...) { + $1 = "%s"; + $2 = (void *) PyString_AsString($input); +} +#endif + +/* Typemap just to make the example work */ +%typemap(in) FILE * "$1 = PyFile_AsFile($input);"; + +int fprintf(FILE *, const char *fmt, ...); + +/* Here is somewhat different example. A variable length argument + function that takes a NULL-terminated list of arguments. We + can use a slightly different form of %varargs that specifies + a default value and a maximum number of arguments. + */ + +/* Maximum of 20 arguments with default value NULL */ + +%varargs(20, char *x = NULL) printv; + +%inline %{ +void printv(char *s, ...) { + va_list ap; + char *x; + fputs(s,stdout); + fputc(' ',stdout); + va_start(ap, s); + while ((x = va_arg(ap, char *))) { + fputs(x,stdout); + fputc(' ',stdout); + } + va_end(ap); + fputc('\n',stdout); +} +%} + diff --git a/trunk/Examples/python/varargs/runme.py b/trunk/Examples/python/varargs/runme.py new file mode 100644 index 000000000..a01cb6769 --- /dev/null +++ b/trunk/Examples/python/varargs/runme.py @@ -0,0 +1,34 @@ +# file: runme.py + +import sys +import example + +# Call printf +example.printf("Hello World. I'm printf\n") + +# Note: We call printf, but use *python* string formatting +for i in range(0,10): + example.printf("i is %d\n" % i) + +# This will probably be garbled because %d is interpreted by C +example.printf("The value is %d\n") + +# Call fprintf +example.fprintf(sys.stdout,"Hello World. I'm fprintf\n") +for i in range(0,10): + example.fprintf(sys.stdout,"i is %d\n" % i) + +# This won't be garbled since %d is not interpreted +example.fprintf(sys.stdout,"The value is %d\n") + +# This function calls our NULL-terminated function + +example.printv("Hello","World","this","is","a","test.") + + + + + + + + diff --git a/trunk/Examples/python/variables/Makefile b/trunk/Examples/python/variables/Makefile new file mode 100644 index 000000000..0f4a1e077 --- /dev/null +++ b/trunk/Examples/python/variables/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-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:: + $(MAKE) -f $(TOP)/Makefile python_clean + rm -f $(TARGET).py + +check: all + $(MAKE) -f $(TOP)/Makefile python_run diff --git a/trunk/Examples/python/variables/example.c b/trunk/Examples/python/variables/example.c new file mode 100644 index 000000000..aa4ffe9b3 --- /dev/null +++ b/trunk/Examples/python/variables/example.c @@ -0,0 +1,91 @@ +/* File : example.c */ + +/* I'm a file containing some C global variables */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include <stdio.h> +#include <stdlib.h> +#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[] = "Goodbye"; +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 = %p\n", iptrvar); + printf("name = %s\n", name); + printf("ptptr = %p (%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/trunk/Examples/python/variables/example.h b/trunk/Examples/python/variables/example.h new file mode 100644 index 000000000..0f7e89594 --- /dev/null +++ b/trunk/Examples/python/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/trunk/Examples/python/variables/example.i b/trunk/Examples/python/variables/example.i new file mode 100644 index 000000000..9d0101cb7 --- /dev/null +++ b/trunk/Examples/python/variables/example.i @@ -0,0 +1,51 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +#pragma SWIG nowarn=SWIGWARN_TYPEMAP_SWIGTYPELEAK + +/* Some global variable declarations */ +%inline %{ +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 */ + +%immutable; + +%inline %{ +extern int status; +extern char path[256]; +%} + +%mutable; + +/* Some helper functions to make it easier to test */ +%inline %{ +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/trunk/Examples/python/variables/index.html b/trunk/Examples/python/variables/index.html new file mode 100644 index 000000000..2940d8a6b --- /dev/null +++ b/trunk/Examples/python/variables/index.html @@ -0,0 +1,100 @@ +<html> +<head> +<title>SWIG:Examples:python:variables</title> +</head> + +<body bgcolor="#ffffff"> + +<tt>SWIG/Examples/python/variables/</tt> +<hr> + +<H2>Wrapping C Global Variables</H2> + +<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 Python variable that magically +retrieves or updates the value of the underlying C variable when it is +accessed. Click <a href="example.i">here</a> to see a SWIG interface with some variable +declarations in it. + +<h2>Manipulating Variables from Python</h2> + +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 '<tt>double a</tt>' you +know that somewhere in memory, 8 bytes have been set aside to hold a +<tt>double</tt> and that <tt>a</tt> 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 '<tt>a = 3</tt>', +'a' becomes a name that refers to some object '3'. Later on, if you say +'<tt>a = 7.5</tt>, 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. + +<p> +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 + +<blockquote> +<pre> +double foo; +</pre> +</blockquote> + +it will be accessed in the Python module as <tt>cvar.foo</tt>. Click +<a href="example.py">here</a> to see a script that updates and prints +out the values of the variables using this technique. + +<h2>Key points</h2> + +<ul> +<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 Python, 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>String array variables such as '<tt>char name[256]</tt>' 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. +<li>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. +</ul> + +<h2>Creating read-only variables</h2> + +The <tt>%immutable</tt> and <tt>%mutable</tt> directives can be used to +specify a collection of read-only variables. For example: + +<blockquote> +<pre> +%immutable; +int status; +double blah; +... +%mutable; +</pre> +</blockquote> + +The <tt>%immutable</tt> directive remains in effect until it is explicitly disabled +using the <tt>%mutable</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>Because of the potential for a namespace conflict, you should not use +the <tt>from module import *</tt> 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. +</ul> + +</body> +</html> +<hr> diff --git a/trunk/Examples/python/variables/runme.py b/trunk/Examples/python/variables/runme.py new file mode 100644 index 000000000..b635b9859 --- /dev/null +++ b/trunk/Examples/python/variables/runme.py @@ -0,0 +1,75 @@ +# file: runme.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.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) + + + |