33
33
<li><a href="#Lua_nn19">Class extension with %extend</a>
34
34
<li><a href="#Lua_nn20">C++ templates</a>
35
35
<li><a href="#Lua_nn21">C++ Smart Pointers</a>
36
<li><a href="#Lua_nn22">Writing your own custom wrappers</a>
36
<li><a href="#Lua_nn22">C++ Exceptions</a>
37
<li><a href="#Lua_nn23">Writing your own custom wrappers</a>
38
<li><a href="#Lua_nn24">Adding additional Lua code</a>
38
<li><a href="#Lua_nn23">Details on the Lua binding</a>
40
<li><a href="#Lua_nn25">Details on the Lua binding</a>
40
<li><a href="#Lua_nn24">Binding global data into the module.</a>
41
<li><a href="#Lua_nn25">Userdata and Metatables</a>
42
<li><a href="#Lua_nn26">Memory management</a>
42
<li><a href="#Lua_nn26">Binding global data into the module.</a>
43
<li><a href="#Lua_nn27">Userdata and Metatables</a>
44
<li><a href="#Lua_nn28">Memory management</a>
949
951
> f = p:__deref__() -- Returns underlying Foo *
952
<H3><a name="Lua_nn22"></a>22.3.15 Writing your own custom wrappers</H3>
956
Sometimes, it may be neccesary to add your own special functions, which bypass the normal SWIG wrappering method, and just use the native lua-c API calls. These 'native' functions allow direct adding of your own code into the module. This is performed with the <tt>%native</tt> directive as follows:
958
<div class="code"><pre>%native(my_func) int native_function(lua_State*L); // registers it with SWIG
954
<H3><a name="Lua_nn22"></a>22.3.15 C++ Exceptions</H3>
958
Lua does not natively support exceptions, but it has errors which are similar. When a Lua function terminates with an error
959
it returns one value back to the caller. SWIG automatically maps any basic type which is thrown into a Lua error.
960
Therefore for a function:
962
<div class="code"><pre>
963
int message() throw(const char *) {
969
SWIG will automatically convert this to a Lua error.
972
<div class="targetlang"><pre>
976
[C]: in function 'message'
977
stdin:1: in main chunk
983
If you want to catch an exception, you must use either pcall() or xpcall(), which are documented in the Lua manual.
984
Using xpcall will allow you to obtain additional debug information (such as a stacktrace).
987
<div class="targetlang"><pre>
988
> function a() b() end -- function a() calls function b()
989
> function b() message() end -- function b() calls C++ function message(), which throws
990
> ok,res=pcall(a) -- call the function
993
> ok,res=xpcall(a,debug.traceback) -- call the function
997
[C]: in function 'message'
998
runme.lua:70: in function 'b'
999
runme.lua:67: in function <runme.lua:66>
1000
[C]: in function 'xpcall'
1001
runme.lua:95: in main chunk
1006
SWIG is able to throw numeric types, enums, chars, char*'s and std::string's without problem.
1007
However its not so simple for to throw objects.
1008
Thrown objects are not valid outside the 'catch' block. Therefore they cannot be
1009
returned to the interpreter.
1010
The obvious ways to overcome this would be to either return a copy of the object, or so convert the object to a string and
1011
return that. Though it seems obvious to perform the former, in some cases this is not possible, most notably when
1012
SWIG has no information about the object, or the object is not copyable/creatable.
1015
Therefore by default SWIG converts all thrown object into strings and returns them. So given a function:
1018
<div class="code"><pre>
1019
void throw_A() throw(A*) {
1024
SWIG will just convert it (poorly) to a string and use that as its error. (Yes its not that useful, but it always works).
1027
<div class="targetlang"><pre>
1029
object exception:A *
1031
[C]: in function 'unknown'
1032
stdin:1: in main chunk
1037
To get a more useful behaviour out of SWIG you must either: provide a way to convert your exceptions into strings, or
1038
throw objects which can be copied.
1041
SWIG has typemaps for std::exception and its children already written, so a function which throws any of these will
1042
automatically have its exception converted into an error string.
1045
If you have your own class which you want output as a string you will need to add a typemap something like this:
1047
<div class="code"><pre>
1048
%typemap(throws) my_except
1050
lua_pushstring(L,$1.what()); // assuming my_except::what() returns a const char* message
1051
SWIG_fail; // trigger the error handler
1055
If you wish your exception to be returned to the interpreter, it must firstly be copyable. Then you must have and additional
1056
<tt>%apply</tt> statement, to inform SWIG to return a copy of this object to the interpreter. For example:
1058
<div class="code"><pre>
1059
%apply SWIGTYPE EXCEPTION_BY_VAL {Exc}; // tell SWIG to return Exc by value to interpreter
1063
Exc(int c, const char *m) {
1071
void throw_exc() throw(Exc) {
1072
throw(Exc(42,"Hosed"));
1076
Then the following code can be used (note: we use pcall to catch the error so we can process the exception).
1078
<div class="targetlang"><pre>
1079
> ok,res=pcall(throw_exc)
1084
> print(res.code,res.msg)
1090
Note: is is also possible (though tedious) to have a function throw several different kinds of exceptions. To process this
1091
will require a pcall, followed by a set of if statements checking the type of the error.
1094
All of this code assumes that your C++ code uses exception specification (which a lot doesn't).
1095
If it doesn't consult the "<a href="SWIGPlus.html#SWIGPlus_catches">Exception handling with %catches</a>" section
1096
and the "<a href="Customization.html#exception">Exception handling with %exception</a>" section, for more details on how to
1097
add exception specification to functions or globally (respectively).
1101
<H3><a name="Lua_nn23"></a>22.3.16 Writing your own custom wrappers</H3>
1105
Sometimes, it may be neccesary to add your own special functions, which bypass the normal SWIG wrappering method, and just use the native Lua API calls. These 'native' functions allow direct adding of your own code into the module. This is performed with the <tt>%native</tt> directive as follows:
1107
<div class="code"><pre>%native(my_func) int native_function(lua_State*L); // registers native_function() with SWIG
961
1110
int native_function(lua_State*L) // my native code
968
1117
The <tt>%native</tt> directive in the above example, tells SWIG that there is a function <tt>int native_function(lua_State*L);</tt> which is to be added into the module under the name '<tt>my_func</tt>'. SWIG will not add any wrappering for this function, beyond adding it into the function table. How you write your code is entirely up to you.
971
<H2><a name="Lua_nn23"></a>22.4 Details on the Lua binding</H2>
1120
<H3><a name="Lua_nn24"></a>22.3.17 Adding additional Lua code</H3>
1124
As well as adding additional C/C++ code, its also possible to add your own Lua code to the module as well.
1125
This code is executed once all other initialisation, including the %init code has been called.
1128
The directive <tt>%luacode</tt> adds code into the module which is executed upon loading. Normally you would
1129
use this to add your own functions to the module. Though you could easily perform other tasks.
1131
<div class="code"><pre>%module example;
1134
function example.greet()
1138
print "Module loaded ok"
1144
Notice that the code is not part of the module table. Therefore any references to the module must have the
1148
Should there be an error in the Lua code, this will <em>not</em> stop loading of the module.
1149
The default behaviour of SWIG is to print a error message to stderr and then continue.
1150
It is possible to change this behaviour by using a <tt>#define SWIG_DOSTRING_FAIL(STR)</tt> to
1151
define a different behaviour should the code fail.
1154
Good uses for this feature is adding of new code, or writing helper functions to simplify some of the code.
1155
See Examples/lua/arrays for an example of this code.
1158
<H2><a name="Lua_nn25"></a>22.4 Details on the Lua binding</H2>