diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html index c534e37cf..fb04ae01c 100644 --- a/Doc/Manual/Contents.html +++ b/Doc/Manual/Contents.html @@ -161,7 +161,7 @@
@@ -91,7 +91,7 @@ Also, this chapter is not meant to be a hand-holding tutorial. As a starting po you should probably look at one of SWIG's existing modules.
-@@ -121,7 +121,7 @@ obvious, but almost all SWIG directives as well as the low-level generation of wrapper code are driven by C++ datatypes.
-@@ -158,7 +158,7 @@ role in making the system work. For example, both typemaps and declaration anno based on pattern matching and interact heavily with the underlying type system.
-@@ -203,7 +203,7 @@ stage of compilation. The next few sections briefly describe some of these stages.
-@@ -283,7 +283,7 @@ been expanded as well as everything else that goes into the low-level construction of the wrapper code.
-@@ -384,7 +384,7 @@ returning a foo and taking types a and b as arguments).
-@@ -636,7 +636,7 @@ $ swig -c++ -python -dump_tree example.i
@@ -655,7 +655,7 @@ that matches the name of the target language. For example, python:foo perl:foo.
-@@ -743,7 +743,7 @@ example.i:5. Previous declaration is foo_i(int )
@@ -799,7 +799,7 @@ For example, the exception code above is simply stored without any modifications.
-@@ -921,7 +921,7 @@ public : The role of these functions is described shortly.
-@@ -934,7 +934,7 @@ internal data structures, it may be useful keep XML in the back of your mind as a model.
-@@ -980,7 +980,7 @@ typedef Hash Typetab; -
@@ -1121,7 +1121,7 @@ Returns the number of replacements made (if any). -
@@ -1198,7 +1198,7 @@ Returns the list of hash table keys. -
@@ -1287,7 +1287,7 @@ If t is not a standard object, it is assumed to be a char * and is used to create a String object. -
@@ -1774,7 +1774,7 @@ the attribute is optional. Swig_restore() must always be called after function. -
@@ -1783,7 +1783,7 @@ pointers, references, and pointers to members. A detailed discussion of type theory is impossible here. However, let's cover the highlights.
-@@ -1884,7 +1884,7 @@ make the final type, the two parts are just joined together using string concatenation.
-@@ -1953,7 +1953,7 @@ Returns nth array dimension of ty.
@@ -2053,7 +2053,7 @@ Returns the prefix of a type. For example, if ty is ty is unmodified. -
@@ -2140,7 +2140,7 @@ Checks if ty is a varargs type. Checks if ty is a templatized type. -
@@ -2242,7 +2242,7 @@ Fully reduces ty according to typedef rules. Resulting datatype will consist only of primitive typenames. -
@@ -2279,7 +2279,7 @@ Literal y; // type = 'Literal', ltype='p.char' -
@@ -2341,7 +2341,7 @@ SWIG, but is most commonly associated with type-descriptor objects that appear in wrappers (e.g., SWIGTYPE_p_double). -
@@ -2440,7 +2440,7 @@ included. Used to emit prototypes. Returns the number of required (non-optional) arguments in p. -
@@ -2451,7 +2451,7 @@ describes the creation of a minimal Python module. You should be able to extra this to other languages.
-@@ -2461,7 +2461,7 @@ the parsing of command line options, all aspects of code generation are controll different methods of the Language that must be defined by your module.
-@@ -2574,7 +2574,7 @@ that activates your module. For example, swig -python foo.i. The messages from your new module should appear.
-@@ -2633,7 +2633,7 @@ to mark the option as valid. If you forget to do this, SWIG will terminate wit unrecognized command line option error.
-@@ -2682,7 +2682,7 @@ an implementation file python.cxx and a configuration file python.swg.
-@@ -2740,13 +2740,13 @@ int Python::top(Node *n) { -
@@ -2910,7 +2910,7 @@ Discuss the kinds of functions typically needed for SWIG runtime support (e.g. the SWIG files that implement those functions.
-@@ -2924,7 +2924,7 @@ Discuss the standard library files that most language modules provide, e.g.
@@ -2951,7 +2951,7 @@ during this process, see the section on configuration files.
-@@ -2983,13 +2983,13 @@ Some topics that you'll want to be sure to address include: if available. -
diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html index 0bcc7f68f..f06cbc609 100644 --- a/Doc/Manual/Java.html +++ b/Doc/Manual/Java.html @@ -6004,7 +6004,9 @@ This example contains some useful functionality which you may want in your code.
Pointers to pointers are often used as output parameters in C factory type functions. These are a bit more tricky to handle. @@ -6103,7 +6105,7 @@ The following interface file code should be placed before SWIG parses the above // Typemaps for Butler ** as a parameter output type %typemap(in) Butler ** (Butler *ppButler = 0) %{ - $1 = &ppButler; + $1 = &ppButler; %} %typemap(argout) Butler ** { // Give Java proxy the C pointer (of newly created object) diff --git a/Doc/Manual/Library.html b/Doc/Manual/Library.html index 9742c160e..60caa600f 100644 --- a/Doc/Manual/Library.html +++ b/Doc/Manual/Library.html @@ -29,6 +29,7 @@
Many of the STL wrapper functions add parameter checking and will throw a language dependent error/exception
should the values not be valid. The classic example is array bounds checking.
@@ -1640,7 +1643,7 @@ For example:
%typemap(throws) std::out_of_range {
// custom exception handler
}
-%template(VectInt) std::vector
- -
Lua is an extension programming language designed to support general procedural programming with data description facilities. It also offers good support for object-oriented programming, functional programming, and data-driven programming. Lua is intended to be used as a powerful, light-weight configuration language for any program that needs one. Lua is implemented as a library, written in clean C (that is, in the common subset of ANSI C and C++). Its also a really tiny language, less than 6000 lines of code, which compiles to <100 kilobytes of binary code. It can be found at http://www.lua.org -
+
The current SWIG implementation is designed to work with Lua 5.0. It should work with later versions of Lua, but certainly not with Lua 4.0 due to substantial API changes. ((Currently SWIG generated code has only been tested on Windows with MingW, though given the nature of Lua, is should not have problems on other OS's)). It is possible to either static link or dynamic link a Lua module into the interpreter (normally Lua static links its libraries, as dynamic linking is not available on all platforms), -
+
Suppose that you defined a SWIG module such as the following: -
+
%module example
%{
@@ -74,26 +71,29 @@ extern double Foo;
To build a Lua module, run SWIG using the -lua option. -
+
$ swig -lua example.i
If building a C++ extension, add the -c++ option: -
+
$ swig -c++ -lua example.i
This creates a C/C++ source file example_wrap.c or example_wrap.cxx. The generated C source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application to create an extension module. +
The name of the wrapper file is derived from the name of the input file. For example, if the input file is example.i, the name of the wrapper file is example_wrap.c. To change this, you can use the -o option. The wrappered module will export one function "int Example_Init(LuaState* L)" which must be called to register the module with the Lua interpreter. The name "Example_Init" depends upon the name of the module. Note: SWIG will automatically capitalise the module name, so "module example;" becomes "Example_Init". -
+
-Normally Lua is embedded into another program and will be statically linked. An extremely simple stand-alone interpreter (min.c) is given below:
+Normally Lua is embedded into another program and will be statically linked. An extremely simple stand-alone interpreter (min.c) is given below: + +#include <stdio.h> #include "lua.h" #include "lualib.h" @@ -122,8 +122,10 @@ int main(int argc,char* argv[])A much improved set of code can be found in the Lua distribution src/lua/lua.c. Include your module, just add the external declaration & add a #define LUA_EXTRALIBS {"example",Example_Init}, at the relevant place. +
The exact commands for doing this vary from platform to platform. Here is a possible set of commands of doing this: +
-$ swig -lua example.i $ gcc -I/usr/include/lua -c min.c -o min.o @@ -131,13 +133,13 @@ $ gcc -I/usr/include/lua -c example_wrap.c -o example_wrap.o $ gcc -c example.c -o example.o $ gcc -I/usr/include/lua -L/usr/lib/lua min.o example_wrap.o example.o -o my_lua+
29.2.2 Compiling a dynamic module
Most, but not all platforms support the dynamic loading of modules (Windows & Linux do). Refer to the Lua manual to determine if your platform supports it. For compiling a dynamically loaded module the same wrapper can be used. The commands will be something like this: -
+
$ swig -lua example.i $ gcc -I/usr/include/lua -c example_wrap.c -o example_wrap.o @@ -146,25 +148,26 @@ $ gcc -shared -I/usr/include/lua -L/usr/lib/lua example_wrap.o example.o -o examYou will also need an interpreter with the loadlib function (such as the default interpreter compiled with Lua). In order to dynamically load a module you must call the loadlib function with two parameters: the filename of the shared library, and the function exported by SWIG. Calling loadlib should return the function, which you then call to initialise the module -
+
my_init=loadlib("example.so","Example_Init") assert(my_init) -- name sure its not nil my_init() -- call the init fn of the lib-Or is can be done in a single line of Lua code -
+Or can be done in a single line of Lua code +
+-assert(loadlib("example.so","Example_Init"))()+
29.2.3 Using your module
Assuming all goes well, you will be able to this: -
+
-$ ./my_lua > print(example.gcd(4,6)) @@ -176,37 +179,40 @@ $ ./my_lua 4 >+
29.3 A tour of basic C/C++ wrapping
By default, SWIG tries to build a very natural Lua interface to your C/C++ code. This section briefly covers the essential aspects of this wrapping. -
+
29.3.1 Modules
The SWIG module directive specifies the name of the Lua module. If you specify `module example', then everything is wrapped into a Lua table 'example' containing all the functions and variables. When choosing a module name, make sure you don't use the same name as a built-in Lua command or standard module name. -
+
29.3.2 Functions
Global functions are wrapped as new Lua built-in functions. For example, -
+
%module example int fact(int n);-creates a built-in function example.fact(n) that works exactly like you think it does:
+creates a built-in function example.fact(n) that works exactly like you think it does: + + +> print example.fact(4) 24 >To avoid name collisions, SWIG create a Lua table which it keeps all the functions and global variables in. It is possible to copy the functions out of this and into the global environment with the following code. This can easily overwrite existing functions, so this must be used with care. -
+
> for k,v in example do _G[k]=v end > print(fact(4)) @@ -215,7 +221,7 @@ To avoid name collisions, SWIG create a Lua table which it keeps all the functioIt is also possible to rename the module with an assignment. -
+
-> e=example > print(e.fact(4)) @@ -223,19 +229,21 @@ It is also possible to rename the module with an assignment. > print(example.fact(4)) 24+
29.3.3 Global variables
Global variables (which are linked to C code) are supported, and appear to be just another variable in Lua. However the actual mechanism is more complex. Given a global variable: -
+
+%module example extern double Foo;SWIG will actually generate two functions example.Foo_set() and example.Foo_get(). It then adds a metatable to the table 'example' to call these functions at the correct time (when you attempt to set or get examples.Foo). Therefore if you were to attempt to assign the global to another variable, you will get a local copy within the interpreter, which is no longer linked to the C code. -
+
+> print(example.Foo) 3 @@ -249,7 +257,7 @@ SWIG will actually generate two functions example.Foo_set() and exaIts is therefore not possible to 'move' the global variable into the global namespace as it is with functions. It is however, possible to rename the module with an assignment, to make it more convenient. -
+
> e=example > -- e and example are the same table @@ -260,9 +268,10 @@ Its is therefore not possible to 'move' the global variable into the global nameIf a variable is marked with the immutable directive then any attempts to set this variable are silently ignored. +
Another interesting feature is that it is not possible to add new values into the module from within the interpreter, this is because of the metatable to deal with global variables. It is possible (though not recommended) to use rawset() to add a new value. -
+
-> -- example.PI does not exist > print(example.PI) @@ -275,20 +284,21 @@ nil > print(example.PI) 3.142+
29.3.4 Constants and enums
Because Lua doesn't really have the concept of constants, C/C++ constants are not really constant in Lua. They are actually just a copy of the value into the Lua interpreter. Therefore they can be changed just as any other value. For example given some constants: -
+
%module example %constant int ICONST=42; #define SCONST "Hello World" enum Days{SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY}; --This is 'effectively' converted into the following Lua code: +
+This is 'effectively' converted into the following Lua code: +
example.ICONST=42 example.SCONST="Hello World" @@ -297,13 +307,13 @@ example.SUNDAY=0Constants are not guaranteed to remain constant in Lua. The name of the constant could be accidentally reassigned to refer to some other object. Unfortunately, there is no easy way for SWIG to generate code that prevents this. You will just have to be careful. -
+
29.3.5 Pointers
C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Given a wrapping of the <file.h> interface: -
+
%module example FILE *fopen(const char *filename, const char *mode); @@ -312,7 +322,7 @@ int fclose(FILE *);When wrapped, you will be able to use the functions in a natural way from Lua. For example: -
+
> f=example.fopen("junk","w") > example.fputs("Hello World",f) @@ -320,7 +330,7 @@ When wrapped, you will be able to use the functions in a natural way from Lua. FUnlike many scripting languages, Lua has had support for pointers to C/C++ object built in for a long time. They are called 'userdata'. Unlike many other SWIG versions which use some kind of encoded character string, all objects will be represented as a userdata. The SWIG-Lua bindings provides a special function swig_type(), which if given a userdata object will return the type of object pointed to as a string (assuming it was a SWIG wrappered object). -
+
> print(f) userdata: 003FDA80 @@ -329,26 +339,26 @@ _p_FILE -- its a FILE*Lua enforces the integrity of its userdata, so it is virtually impossible to corrupt the data. But as the user of the pointer, you are responsible for freeing it, or closing any resources associated with it (just as you would in a C program). This does not apply so strictly to classes & structs (see below). One final note: if a function returns a NULL pointer, this is not encoded as a userdata, but as a Lua nil. -
+
-> f=example.fopen("not there","r") -- this will return a NULL in C > print(f) nil+
29.3.6 Structures
If you wrap a C structure, it is also mapped to a Lua userdata. By adding a metatable to the userdata, this provides a very natural interface. For example, -
+
struct Point{ int x,y; };is used as follows: -
+
> p=example.Point() > p.x=3 @@ -360,18 +370,20 @@ is used as follows:Similar access is provided for unions and the data members of C++ classes.
SWIG will also create a function new_Point() which also creates a new Point structure. +If you print out the value of p in the above example, you will see something like this: -
+
> print(p) userdata: 003FA320Like the pointer in the previous section, this is held as a userdata. However, additional features have been added to make this more usable. SWIG creates some accessor/mutator functions Point_set_x() and Point_get_x(). These will be wrappered, and then added to the metatable added to the userdata. This provides the natural access to the member variables that were shown above (see end of the document for full details). +
const members of a structure are read-only. Data members can also be forced to be read-only using the immutable directive. As with other immutable's, setting attempts will be silently ignored. For example: -
+
struct Foo { ... %immutable; @@ -383,9 +395,11 @@ Like the pointer in the previous section, this is held as a userdata. However, aThe mechanism for managing char* members as well as array members is similar to other languages. It is somewhat cumbersome and should probably be better handled by defining of typemaps (described later). +
When a member of a structure is itself a structure, it is handled as a pointer. For example, suppose you have two structures like this: -
+
+struct Foo { int a; }; @@ -395,29 +409,35 @@ struct Bar { };-Now, suppose that you access the f attribute of Bar like this:
+Now, suppose that you access the f attribute of Bar like this: + +> b = Bar() > x = b.f-In this case, x is a pointer that points to the Foo that is inside b. This is the same value as generated by this C code:
+In this case, x is a pointer that points to the Foo that is inside b. This is the same value as generated by this C code: + +Bar b; Foo *x = &b->f; // Points inside b-Because the pointer points inside the structure, you can modify the contents and everything works just like you would expect. For example:
+Because the pointer points inside the structure, you can modify the contents and everything works just like you would expect. For example: + +-> b = Bar() > b.f.a = 3 -- Modify attribute of structure member > x = b.f > x.a = 3 -- Modifies the same structure+
29.3.7 C++ classes
C++ classes are wrapped by a Lua userdata as well. For example, if you have this class, -
+
class List { public: List(); @@ -430,7 +450,9 @@ public: };-you can use it in Lua like this:
+you can use it in Lua like this: + +> l = example.List() > l.insert("Ale") > l.insert("Stout") @@ -443,7 +465,7 @@ StoutClass data members are accessed in the same manner as C structures. Static class members present a special problem for Lua, as Lua doesn't have support for such features. Therefore, SWIG generates wrappers that try to work around some of these issues. To illustrate, suppose you have a class like this: -
+
class Spam { public: static void foo(); @@ -452,7 +474,9 @@ public: };-In Lua, the static members can be accessed as follows:
+In Lua, the static members can be accessed as follows: + +> example.Spam_foo() -- Spam::foo() the only way currently > a=example.Spam_bar_get() -- Spam::bar the hard way > a=example.Spam_bar -- Spam::bar the nicer way @@ -460,18 +484,20 @@ In Lua, the static members can be accessed as follows:> example.Spam_bar=b -- Spam::bar the nicer way-It is not (currently) possible to access static members of an instance:
+It is not (currently) possible to access static members of an instance: + +-> s=example.Spam() -- s is a Spam instance > s.foo() -- Spam::foo() via an instance -- does NOT work+
29.3.8 C++ inheritance
SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have classes like this -
+
class Foo { ... }; @@ -482,20 +508,21 @@ class Bar : public Foo {And if you have functions like this -
+
void spam(Foo *f);then the function spam() accepts a Foo pointer or a pointer to any class derived from Foo. +
It is safe to use multiple inheritance with SWIG. -
+
29.3.9 Pointers, references, values, and arrays
In C++, there are many different ways a function might receive and manipulate objects. For example: -
+
void spam1(Foo *x); // Pass by pointer void spam2(Foo &x); // Pass by reference void spam3(Foo x); // Pass by value @@ -503,7 +530,7 @@ void spam4(Foo x[]); // Array of objectsIn SWIG, there is no detailed distinction like this--specifically, there are only "objects". There are no pointers, references, arrays, and so forth. Because of this, SWIG unifies all of these types together in the wrapper code. For instance, if you actually had the above functions, it is perfectly legal to do this: -
+
> f = Foo() -- Create a Foo > spam1(f) -- Ok. Pointer @@ -513,41 +540,42 @@ In SWIG, there is no detailed distinction like this--specifically, there are onlSimilar behaviour occurs for return values. For example, if you had functions like this, -
+
Foo *spam5(); Foo &spam6(); Foo spam7();then all three functions will return a pointer to some Foo object. Since the third function (spam7) returns a value, newly allocated memory is used to hold the result and a pointer is returned (Lua will release this memory when the return value is garbage collected). The other two are pointers which are assumed to be managed by the C code and so will not be garbage collected. -
+
29.3.10 C++ overloaded functions
C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, if you have two functions like this: -
+
void foo(int); void foo(char *c);You can use them in Lua in a straightforward manner: -
+
> foo(3) -- foo(int) > foo("Hello") -- foo(char *c)However due to Lua's coercion mechanism is can sometimes do strange things. -
+
> foo("3") -- "3" can be coerced into an int, so it calls foo(int)!As this coercion mechanism is an integral part of Lua, there is no easy way to get around this other than renaming of functions (see below). +
Similarly, if you have a class like this, -
+
class Foo { public: Foo(); @@ -557,32 +585,33 @@ public:you can write Lua code like this: -
+
> f = Foo() -- Create a Foo > g = Foo(f) -- Copy fOverloading support is not quite as flexible as in C++. Sometimes there are methods that SWIG can't disambiguate. For example: -
+
void spam(int); void spam(short);or -
-
void foo(Bar *b); + +VOID FOO(bAR *B); void foo(Bar &b);If declarations such as these appear, you will get a warning message like this: -
+
example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int) at example.i:11. -- To fix this, you either need to ignore or rename one of the methods. For example: +
+ To fix this, you either need to ignore or rename one of the methods. For example: +
%rename(spam_short) spam(short); ... void spam(int); @@ -590,7 +619,7 @@ void spam(short); // Accessed as spam_shortor -
+
%ignore spam(short); ... void spam(int); @@ -598,17 +627,19 @@ void spam(short); // IgnoredSWIG resolves overloaded functions and methods using a disambiguation scheme that ranks and sorts declarations according to a set of type-precedence rules. The order in which declarations appear in the input does not matter except in situations where ambiguity arises--in this case, the first declaration takes precedence. +
Please refer to the "SWIG and C++" chapter for more information about overloading. +
Dealing with the Lua coercion mechanism, the priority is roughly (integers, floats, strings, userdata). But it is better to rename the functions rather than rely upon the ordering. -
+
29.3.11 C++ operators
Certain C++ overloaded operators can be handled automatically by SWIG. For example, consider a class like this: -
+
class Complex { private: double rpart, ipart; @@ -627,7 +658,7 @@ public:When wrapped, it works like you expect: -
+
-> c = Complex(3,4) > d = Complex(7,8) @@ -637,10 +668,12 @@ When wrapped, it works like you expect: > e:im() 12.0(Note: for calling methods of a class, you use class:method(args), not class.method(args), its an easy mistake to make.) +
+(Note: for calling methods of a class, you use class:method(args), not class.method(args), its an easy mistake to make.) +
One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class. For example, if you had code like this -
+
class Complex { ... friend Complex operator+(double, const Complex &c); @@ -649,15 +682,17 @@ friend Complex operator+(double, const Complex &c);then SWIG doesn't know what to do with the friend function--in fact, it simply ignores it and issues a warning. You can still wrap the operator, but you may have to encapsulate it in a special function. For example: -
+
%rename(Complex_add_dc) operator+(double, const Complex &); ... Complex operator+(double, const Complex &c);There are ways to make this operator appear as part of the class using the %extend directive. Keep reading. +
Also, be aware that certain operators don't map cleanly to Lua, and some Lua operators don't map cleanly to C++ operators. For instance, overloaded assignment operators don't map to Lua semantics and will be ignored, and C++ doesn't support Lua's concatenation operator (..). +
In order to keep maximum compatibility within the different languages in SWIG, the Lua bindings uses the same set of operator names as python. Although internally it renames the functions to something else (on order to work with Lua).
@@ -673,13 +708,16 @@ The current list of operators which can be overloaded (and the alternative funct
- __eq__ operator==
- __lt__ operator<
- __le__ operator<= -
+ +
Note: in Lua, only the equals, less than, and less than equals operators are defined. The other operators (!=,>,>=) are achieved by using a logical not applied to the results of other operators. +
The following operators cannot be overloaded (mainly because they are not supported in Lua)
-
- ++ and --
- +=,-=,*= etc
- % operator (you have to use math.mod)
- assignment operator
- all bitwise/logical operations
SWIG also accepts the __str__() member function which converts an object to a string. This function should return a const char*, preferably to static memory. This will be used for the print() and tostring() functions in Lua. Assuming the complex class has a function
+SWIG also accepts the __str__() member function which converts an object to a string. This function should return a const char*, preferably to static memory. This will be used for the print() and tostring() functions in Lua. Assuming the complex class has a function +
const char* __str__() { static char buffer[255]; @@ -688,7 +726,9 @@ The following operators cannot be overloaded (mainly because they are not suppor }-Then this will support the following code in Lua
+Then this will support the following code in Lua + +> c = Complex(3,4) > d = Complex(7,8) > e = c + d @@ -700,6 +740,7 @@ Complex(10,12)It is also possible to overload the operator[], but currently this cannot be automatically performed. To overload the operator[] you need to provide two functions, __getitem__() and __setitem__() +
-class Complex { //.... @@ -707,15 +748,16 @@ It is also possible to overload the operator[], but currently this cann void __setitem__(int i,double d); // i is the index, d is the data };+
29.3.12 Class extension with %extend
One of the more interesting features of SWIG is that it can extend structures and classes with new methods. In the previous section, the Complex class would have benefited greatly from an __str__() method as well as some repairs to the operator overloading. It can also be used to add additional functions to the class if they are needed. +
Take the original Complex class -
+
class Complex { private: double rpart, ipart; @@ -733,7 +775,9 @@ public: };-Now we extend it with some new code
%extend Complex { +Now we extend it with some new code + +%extend Complex { const char *__str__() { static char tmp[1024]; sprintf(tmp,"Complex(%g,%g)", self->re(),self->im()); @@ -745,7 +789,7 @@ Now we extend it with some new code%extend Complex {Now, in Lua -
+
> c = Complex(3,4) > d = Complex(7,8) @@ -759,13 +803,13 @@ trueExtend works with both C and C++ code, on classes and structs. It does not modify the underlying object in any way---the extensions only show up in the Lua interface. The only item to take note of is the code has to use the 'self' instead of 'this', and that you cannot access protected/private members of the code (as you are not officially part of the class). -
+
29.3.13 C++ templates
C++ templates don't present a huge problem for SWIG. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation. To do this, you use the template directive. For example: -
+
%module example %{ #include "pair.h" @@ -786,7 +830,7 @@ struct pair {In Lua: -
+
> p = example.pairii(3,4) > print(p.first,p.second) @@ -794,13 +838,13 @@ In Lua:Obviously, there is more to template wrapping than shown in this example. More details can be found in the SWIG and C++ chapter. Some more complicated examples will appear later. -
+
29.3.14 C++ Smart Pointers
In certain C++ programs, it is common to use classes that have been wrapped by so-called "smart pointers." Generally, this involves the use of a template class that implements operator->() like this: -
+
template<class T> class SmartPtr { ... T *operator->(); @@ -809,7 +853,7 @@ Obviously, there is more to template wrapping than shown in this example. More dThen, if you have a class like this, -
+
class Foo { public: int x; @@ -818,7 +862,7 @@ public:A smart pointer would be used in C++ as follows: -
+
SmartPtr<Foo> p = CreateFoo(); // Created somehow (not shown) ... p->x = 3; // Foo::x @@ -826,7 +870,7 @@ int y = p->bar(); // Foo::barTo wrap this, simply tell SWIG about the SmartPtr class and the low-level Foo object. Make sure you instantiate SmartPtr using template if necessary. For example: -
+
%module example ... %template(SmartPtrFoo) SmartPtr<Foo>; @@ -834,7 +878,7 @@ To wrap this, simply tell SWIG about the SmartPtr class and the low-level Foo obNow, in Lua, everything should just "work": -
+
> p = example.CreateFoo() -- Create a smart-pointer somehow > p.x = 3 -- Foo::x @@ -842,36 +886,39 @@ Now, in Lua, everything should just "work":If you ever need to access the underlying pointer returned by operator->() itself, simply use the __deref__() method. For example: -
+
-> f = p:__deref__() -- Returns underlying Foo *+
29.4 Details on the Lua binding
In the previous section, a high-level view of Lua wrapping was presented. Obviously a lot of stuff happens behind the scenes to make this happen. This section will explain some of the low-level details on how this is achieved. +
If you just want to use SWIG and don't care how it works, then stop reading here. This is going into the guts of the code and how it works. Its mainly for people who need to know whats going on within the code. -
+
+29.4.1 Binding global data into the module.
Assuming that you had some global data that you wanted to share between C and Lua. How does SWIG do it? -
+
%module example; extern double Foo;SWIG will effectively generate the pair of functions
void Foo_set(double); double Foo_get(); +At initialisation time, it will then add to the interpreter a table called 'example', which represents the module. It will then add all its functions to the module. But it also adds a metatable to this table, which has two functions (__index and __newindex) as well as two tables (.get and .set) The following Lua code will show these hidden features. -
+
> print(example) table: 003F8F90 @@ -888,8 +935,10 @@ Foo function: 003FAFD8The .get and .set tables are lookups connecting the variable name 'Foo' to the accessor/mutator functions (Foo_set,Foo_get) +
The Lua equivalent of the code for the __index and __newindex looks a bit like this +
function __index(mod,name) local g=getmetatable(mod)['.get'] -- gets the table @@ -910,16 +959,20 @@ endThat way when you call 'a=example.Foo', the interpreter looks at the table 'example' sees that there is no field 'Foo' and calls __index. This will in turn check in '.get' table and find the existence of 'Foo' and then return the value of the C function call 'Foo_get()'. Similarly for the code 'example.Foo=10', the interpreter will check the table, then call the __newindex which will then check the '.set' table and call the C function 'Foo_set(10)'. -
+
29.4.2 Userdata and Metatables
As mentioned earlier, classes and structures, are all held as pointer, using the Lua 'userdata' structure. This structure is actually a pointer to a C structure 'swig_lua_userdata', which contains the pointer to the data, a pointer to the swig_type_info (an internal SWIG struct) and a flag which marks if the object is to be disposed of when the interpreter no longer needs it. The actual accessing of the object is done via the metatable attached to this userdata. +
The metatable is a Lua 5.0 feature (which is also why SWIG cannot wrap Lua 4.0). Its a table which holds a list of functions, operators and attributes. This is what gives the userdata the feeling that it is a real object and not just a hunk of memory. +
-Given a class
%module excpp; +Given a class + +%module excpp; class Point { @@ -932,9 +985,10 @@ public:SWIG will create a module excpp, with all the various function inside. However to allow the intuitive use of the userdata is also creates up a set of metatables. As seen in the above section on global variables, use of the metatables allows for wrappers to be used intuitively. To save effort, the code creates one metatable per class and stores it inside Lua's registry. Then when an new object is instantiated, the metatable is found in the registry and the userdata associated to the metatable. Currently derived classes make a complete copy of the base classes table and then add on their own additional function. +
Some of the internals can be seen by looking at a classes metatable. -
+
> p=excpp.Point() > print(p) @@ -951,8 +1005,11 @@ __index function: 003FB698The '.type' attribute is the string which is returned from a call to swig_type(). The '.get' and '.set' tables work in a similar manner to the modules, the main difference is the '.fn' table which also holds all the member functions. (The '__gc' function is the classes destructor function) +
-The Lua equivalent of the code for enabling functions looks a little like this
+The Lua equivalent of the code for enabling functions looks a little like this + +function __index(obj,name) local m=getmetatable(obj) -- gets the metatable if not m then return nil end @@ -973,22 +1030,27 @@ endSo when 'p:Print()' is called, the __index looks on the object metatable for a 'Print' attribute, then looks for a 'Print' function. When it finds the function, it returns the function, and then interpreter can call 'Point_Print(p)' +
In theory, you can play with this usertable & add new features, but remember that it is a shared table between all instances of one class, and you could very easily corrupt the functions in all the instances. +
Note: Both the opaque structures (like the FILE*) and normal wrappered classes/structs use the same 'swig_lua_userdata' structure. Though the opaque structures has do not have a metatable attached, or any information on how to dispose of them when the interpreter has finished with them. +
Note: Operator overloads are basically done in the same way, by adding functions such as '__add' & '__call' to the classes metatable. The current implementation is a bit rough as it will add any member function beginning with '__' into the metatable too, assuming its an operator overload. -
+
29.4.3 Memory management
Lua is very helpful with the memory management. The 'swig_lua_userdata' is fully managed by the interpreter itself. This means that neither the C code nor the Lua code can damage it. Once a piece of userdata has no references to it, it is not instantly collected, but will be collected when Lua deems is necessary. (You can force collection by calling the Lua function collectgarbage()). Once the userdata is about to be free'ed, the interpreter will check the userdata for a metatable and for a function '__gc'. If this exists this is called. For all complete types (ie normal wrappered classes & structs) this should exist. The '__gc' function will check the 'swig_lua_userdata' to check for the 'own' field and if this is true (which is will be for all owned data's) it will then call the destructor on the pointer. +
It is currently not recommended to edit this field or add some user code, to change the behaviour. Though for those who wish to try, here is where to look. +
-Is is also currently not possible to change the ownership flag on the data (unlike most other scripting languages, Lua does not permit access to the data from within the interpreter) -
+It is also currently not possible to change the ownership flag on the data (unlike most other scripting languages, Lua does not permit access to the data from within the interpreter) +