[lua] Added a typemap DISOWN for SWIGTYPE* and SWIGTYPE[], and support for %delobject feature.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@10326 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
97b910d726
commit
11647d87e8
14 changed files with 377 additions and 19 deletions
|
|
@ -1,6 +1,10 @@
|
||||||
Version 1.3.35 (in progress)
|
Version 1.3.35 (in progress)
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
03/27/2008: mgossage
|
||||||
|
[Lua] Added a typemap DISOWN for SWIGTYPE* and SWIGTYPE[], and support for %delobject feature.
|
||||||
|
Added Examples/lua/owner which demonstrates the use of the memory management.
|
||||||
|
|
||||||
03/26/2008: wsfulton
|
03/26/2008: wsfulton
|
||||||
[Java] Apply patch #1844301 from Monty Taylor to suppress enum constructor
|
[Java] Apply patch #1844301 from Monty Taylor to suppress enum constructor
|
||||||
unused warnings.
|
unused warnings.
|
||||||
|
|
|
||||||
|
|
@ -980,10 +980,32 @@ stack traceback:
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
And similarly for numeric types, enums, chars, char*'s and std::string's.
|
If you want to catch an exception, you must use either pcall() or xpcall(), which are documented in the Lua manual.
|
||||||
|
Using xpcall will allow you to obtain additional debug information (such as a stacktrace).
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<div class="targetlang"><pre>
|
||||||
|
> function a() b() end -- function a() calls function b()
|
||||||
|
> function b() message() end -- function b() calls C++ function message(), which throws
|
||||||
|
> ok,res=pcall(a) -- call the function
|
||||||
|
> print(ok,res)
|
||||||
|
false I died.
|
||||||
|
> ok,res=xpcall(a,debug.traceback) -- call the function
|
||||||
|
> print(ok,res)
|
||||||
|
false I died.
|
||||||
|
stack traceback:
|
||||||
|
[C]: in function 'message'
|
||||||
|
runme.lua:70: in function 'b'
|
||||||
|
runme.lua:67: in function <runme.lua:66>
|
||||||
|
[C]: in function 'xpcall'
|
||||||
|
runme.lua:95: in main chunk
|
||||||
|
[C]: ?
|
||||||
|
</pre></div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
However its not so simple for objects. Thrown objects are not valid outside the 'catch' block. Therefore they cannot be
|
SWIG is able to throw numeric types, enums, chars, char*'s and std::string's without problem.
|
||||||
|
However its not so simple for to throw objects.
|
||||||
|
Thrown objects are not valid outside the 'catch' block. Therefore they cannot be
|
||||||
returned to the interpreter.
|
returned to the interpreter.
|
||||||
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
|
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
|
||||||
return that. Though it seems obvious to perform the former, in some cases this is not possible, most notably when
|
return that. Though it seems obvious to perform the former, in some cases this is not possible, most notably when
|
||||||
|
|
@ -1013,7 +1035,7 @@ stack traceback:
|
||||||
</pre></div>
|
</pre></div>
|
||||||
<p>
|
<p>
|
||||||
To get a more useful behaviour out of SWIG you must either: provide a way to convert your exceptions into strings, or
|
To get a more useful behaviour out of SWIG you must either: provide a way to convert your exceptions into strings, or
|
||||||
only throw objects which can be copied.
|
throw objects which can be copied.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
SWIG has typemaps for std::exception and its children already written, so a function which throws any of these will
|
SWIG has typemaps for std::exception and its children already written, so a function which throws any of these will
|
||||||
|
|
@ -1025,7 +1047,7 @@ If you have your own class which you want output as a string you will need to ad
|
||||||
<div class="code"><pre>
|
<div class="code"><pre>
|
||||||
%typemap(throws) my_except
|
%typemap(throws) my_except
|
||||||
%{
|
%{
|
||||||
lua_pushstring(L,$1.what()); // assuming what() returns a const char* message
|
lua_pushstring(L,$1.what()); // assuming my_except::what() returns a const char* message
|
||||||
SWIG_fail; // trigger the error handler
|
SWIG_fail; // trigger the error handler
|
||||||
%}
|
%}
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
@ -1063,6 +1085,7 @@ userdata: 0003D880
|
||||||
42 Hosed
|
42 Hosed
|
||||||
>
|
>
|
||||||
</pre></div>
|
</pre></div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Note: is is also possible (though tedious) to have a function throw several different kinds of exceptions. To process this
|
Note: is is also possible (though tedious) to have a function throw several different kinds of exceptions. To process this
|
||||||
will require a pcall, followed by a set of if statements checking the type of the error.
|
will require a pcall, followed by a set of if statements checking the type of the error.
|
||||||
|
|
@ -1129,7 +1152,7 @@ define a different behaviour should the code fail.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Good uses for this feature is adding of new code, or writing helper functions to simplify some of the code.
|
Good uses for this feature is adding of new code, or writing helper functions to simplify some of the code.
|
||||||
See Examples/lua/arrays, for an example of this code.
|
See Examples/lua/arrays for an example of this code.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<H2><a name="Lua_nn25"></a>22.4 Details on the Lua binding</H2>
|
<H2><a name="Lua_nn25"></a>22.4 Details on the Lua binding</H2>
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ funcptr3
|
||||||
functest
|
functest
|
||||||
functor
|
functor
|
||||||
import
|
import
|
||||||
|
owner
|
||||||
pointer
|
pointer
|
||||||
simple
|
simple
|
||||||
variables
|
variables
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ int main(int argc,char* argv[]) {
|
||||||
int ok;
|
int ok;
|
||||||
int res;
|
int res;
|
||||||
char str[80];
|
char str[80];
|
||||||
printf("[C] Welcome to the simple embedded Lua example\n");
|
printf("[C] Welcome to the simple embedded Lua example v2\n");
|
||||||
printf("[C] We are in C\n");
|
printf("[C] We are in C\n");
|
||||||
printf("[C] opening a Lua state & loading the libraries\n");
|
printf("[C] opening a Lua state & loading the libraries\n");
|
||||||
L=lua_open();
|
L=lua_open();
|
||||||
|
|
|
||||||
|
|
@ -61,3 +61,36 @@ for i=1,3 do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- this is a bit crazy, but it shows obtaining of the stacktrace
|
||||||
|
function a()
|
||||||
|
b()
|
||||||
|
end
|
||||||
|
function b()
|
||||||
|
t:message()
|
||||||
|
end
|
||||||
|
print [[
|
||||||
|
Now lets call function a()
|
||||||
|
which calls b()
|
||||||
|
which calls into C++
|
||||||
|
which will throw an exception!]]
|
||||||
|
ok,res=pcall(a)
|
||||||
|
if ok then
|
||||||
|
print " that worked! Funny"
|
||||||
|
else
|
||||||
|
print(" call failed with error:",res)
|
||||||
|
end
|
||||||
|
print "Now lets do the same using xpcall(a,debug.traceback)"
|
||||||
|
ok,res=xpcall(a,debug.traceback)
|
||||||
|
if ok then
|
||||||
|
print " that worked! Funny"
|
||||||
|
else
|
||||||
|
print(" call failed with error:",res)
|
||||||
|
end
|
||||||
|
print "As you can see, the xpcall gives a nice stacktrace to work with"
|
||||||
|
|
||||||
|
|
||||||
|
ok,res=pcall(a)
|
||||||
|
print(ok,res)
|
||||||
|
ok,res=xpcall(a,debug.traceback)
|
||||||
|
print(ok,res)
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,6 @@ for i=0,100 do
|
||||||
a(i) -- Note: function call
|
a(i) -- Note: function call
|
||||||
b(math.sqrt(i)) -- Note: function call
|
b(math.sqrt(i)) -- Note: function call
|
||||||
end
|
end
|
||||||
print("int sum 0..100 is",a:result(),"(expected 5050")
|
print("int sum 0..100 is",a:result(),"(expected 5050)")
|
||||||
print("double sum 0..100 is",b:result(),"(expected ~771.46)")
|
print("double sum 0..100 is",b:result(),"(expected ~771.46)")
|
||||||
|
|
||||||
|
|
|
||||||
19
Examples/lua/owner/Makefile
Normal file
19
Examples/lua/owner/Makefile
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
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)' lua_cpp
|
||||||
|
|
||||||
|
static::
|
||||||
|
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
|
||||||
|
TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
|
||||||
|
|
||||||
|
clean::
|
||||||
|
$(MAKE) -f $(TOP)/Makefile lua_clean
|
||||||
|
|
||||||
|
check: all
|
||||||
67
Examples/lua/owner/example.cxx
Normal file
67
Examples/lua/owner/example.cxx
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Circle* createCircle(double w)
|
||||||
|
{
|
||||||
|
return new Circle(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
Square* createSquare(double w)
|
||||||
|
{
|
||||||
|
return new Square(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
ShapeOwner::ShapeOwner() {printf(" ShapeOwner(%p)\n",this);}
|
||||||
|
ShapeOwner::~ShapeOwner()
|
||||||
|
{
|
||||||
|
printf(" ~ShapeOwner(%p)\n",this);
|
||||||
|
for(unsigned i=0;i<shapes.size();i++)
|
||||||
|
delete shapes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShapeOwner::add(Shape* ptr) // this method takes ownership of the object
|
||||||
|
{
|
||||||
|
shapes.push_back(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shape* ShapeOwner::get(int idx) // this pointer is still owned by the class (assessor)
|
||||||
|
{
|
||||||
|
if (idx<0 || idx>=shapes.size())
|
||||||
|
return NULL;
|
||||||
|
return shapes[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
Shape* ShapeOwner::remove(int idx) // this method returns memory which must be deleted
|
||||||
|
{
|
||||||
|
if (idx<0 || idx>=shapes.size())
|
||||||
|
return NULL;
|
||||||
|
Shape* ptr=shapes[idx];
|
||||||
|
shapes.erase(shapes.begin()+idx);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
54
Examples/lua/owner/example.h
Normal file
54
Examples/lua/owner/example.h
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/* File : example.h */
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Circle* createCircle(double w); // this method creates a new object
|
||||||
|
Square* createSquare(double w); // this method creates a new object
|
||||||
|
|
||||||
|
class ShapeOwner {
|
||||||
|
private:
|
||||||
|
std::vector<Shape*> shapes;
|
||||||
|
ShapeOwner(const ShapeOwner&); // no copying
|
||||||
|
ShapeOwner& operator=(const ShapeOwner&); // no copying
|
||||||
|
public:
|
||||||
|
ShapeOwner();
|
||||||
|
~ShapeOwner();
|
||||||
|
void add(Shape* ptr); // this method takes ownership of the object
|
||||||
|
Shape* get(int idx); // this pointer is still owned by the class (assessor)
|
||||||
|
Shape* remove(int idx); // this method returns memory which must be deleted
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
35
Examples/lua/owner/example.i
Normal file
35
Examples/lua/owner/example.i
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
/* File : example.i */
|
||||||
|
%module example
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include "example.h"
|
||||||
|
%}
|
||||||
|
|
||||||
|
// before we grab the header file, we must warn SWIG about some of these functions.
|
||||||
|
|
||||||
|
// these functions create data, so must be managed
|
||||||
|
%newobject createCircle;
|
||||||
|
%newobject createSquare;
|
||||||
|
|
||||||
|
// this method returns as pointer which must be managed
|
||||||
|
%newobject ShapeOwner::remove;
|
||||||
|
|
||||||
|
// you cannot use %delobject on ShapeOwner::add()
|
||||||
|
// as this disowns the ShapeOwner, not the Shape (oops)
|
||||||
|
//%delobject ShapeOwner::add(Shape*); DO NOT USE
|
||||||
|
|
||||||
|
// either you can use a new function (such as this)
|
||||||
|
/*%delobject add_Shape;
|
||||||
|
%inline %{
|
||||||
|
void add_Shape(Shape* s,ShapeOwner* own){own->add(s);}
|
||||||
|
%}*/
|
||||||
|
|
||||||
|
// or a better solution is a typemap
|
||||||
|
%apply SWIGTYPE *DISOWN {Shape* ptr};
|
||||||
|
|
||||||
|
|
||||||
|
//%ignore ShapeOwner::add;
|
||||||
|
|
||||||
|
// now we can grab the header file
|
||||||
|
%include "example.h"
|
||||||
|
|
||||||
104
Examples/lua/owner/runme.lua
Normal file
104
Examples/lua/owner/runme.lua
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
-- Operator overloading example
|
||||||
|
---- importing ----
|
||||||
|
if string.sub(_VERSION,1,7)=='Lua 5.0' then
|
||||||
|
-- lua5.0 doesnt have a nice way to do this
|
||||||
|
lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
|
||||||
|
assert(lib)()
|
||||||
|
else
|
||||||
|
-- lua 5.1 does
|
||||||
|
require('example')
|
||||||
|
end
|
||||||
|
|
||||||
|
print "ok, lets test Lua's ownership of C++ objects"
|
||||||
|
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
|
||||||
|
|
||||||
|
print "\nLets make a couple"
|
||||||
|
a=example.Square(10)
|
||||||
|
b=example.Circle(1)
|
||||||
|
print("Currently there are",example.Shape_nshapes,"shapes (there should be 2)")
|
||||||
|
|
||||||
|
print "\nNote lets use the createX functions"
|
||||||
|
c=example.createCircle(5)
|
||||||
|
d=example.createSquare(3)
|
||||||
|
print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")
|
||||||
|
|
||||||
|
print "\nWe will run the garbage collector & see if they are till here"
|
||||||
|
collectgarbage()
|
||||||
|
print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")
|
||||||
|
|
||||||
|
print "\nLets get rid of them all, collect garbage & see if they are till here"
|
||||||
|
a,b,c,d=nil,nil,nil,nil
|
||||||
|
collectgarbage()
|
||||||
|
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
|
||||||
|
|
||||||
|
print "\nLets start putting stuff into the ShapeOwner"
|
||||||
|
print "The ShapeOwner now owns the shapes, but Lua still has pointers to them"
|
||||||
|
o=example.ShapeOwner()
|
||||||
|
a=example.Square(10)
|
||||||
|
b=example.Circle(1)
|
||||||
|
o:add(a)
|
||||||
|
o:add(b)
|
||||||
|
o:add(example.createSquare(5))
|
||||||
|
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
|
||||||
|
|
||||||
|
print "\nWe will nil our references,run the garbage collector & see if they are till here"
|
||||||
|
print "they should be, as the ShapeOwner owns them"
|
||||||
|
a,b=nil,nil
|
||||||
|
collectgarbage()
|
||||||
|
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
|
||||||
|
|
||||||
|
print "\nWe will access them and check that they are still valid"
|
||||||
|
a=o:get(0)
|
||||||
|
b=o:get(1)
|
||||||
|
print(" Area's are",a:area(),b:area(),o:get(2):area())
|
||||||
|
collectgarbage()
|
||||||
|
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
|
||||||
|
|
||||||
|
print "\nWe will remove one from the C++ owner & pass its ownership to Lua,"
|
||||||
|
print " then check that they are still unchanged"
|
||||||
|
a,b=nil,nil
|
||||||
|
a=o:remove(0) -- a now owns it
|
||||||
|
collectgarbage()
|
||||||
|
print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
|
||||||
|
|
||||||
|
print "\nDelete the ShapeOwner (this should destroy two shapes),"
|
||||||
|
print " but we have one left in Lua"
|
||||||
|
o=nil
|
||||||
|
collectgarbage()
|
||||||
|
print("Currently there are",example.Shape_nshapes,"shapes (there should be 1)")
|
||||||
|
|
||||||
|
print "\nFinal tidy up "
|
||||||
|
a=nil
|
||||||
|
collectgarbage()
|
||||||
|
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
|
||||||
|
|
||||||
|
|
||||||
|
print "Final test, we will create some Shapes & pass them around like mad"
|
||||||
|
print "If there is any memory leak, you will see it in the memory usage"
|
||||||
|
io.flush()
|
||||||
|
sh={}
|
||||||
|
-- make some objects
|
||||||
|
for i=0,10 do
|
||||||
|
a=example.Circle(i)
|
||||||
|
b=example.Square(i)
|
||||||
|
sh[a]=true
|
||||||
|
sh[b]=true
|
||||||
|
end
|
||||||
|
o=example.ShapeOwner()
|
||||||
|
for i=0,10000 do
|
||||||
|
for k,_ in pairs(sh) do
|
||||||
|
o:add(k)
|
||||||
|
end
|
||||||
|
sh={} -- clear it
|
||||||
|
while true do
|
||||||
|
a=o:remove(0)
|
||||||
|
if a==nil then break end
|
||||||
|
sh[a]=true
|
||||||
|
end
|
||||||
|
if i%100==0 then collectgarbage() end
|
||||||
|
end
|
||||||
|
print "done"
|
||||||
|
o,sh=nil,nil
|
||||||
|
collectgarbage()
|
||||||
|
print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
|
||||||
|
print "thats all folks!"
|
||||||
|
|
@ -600,11 +600,15 @@ SWIGRUNTIME int SWIG_Lua_ConvertPtr(lua_State* L,int index,void** ptr,swig_type
|
||||||
usr=(swig_lua_userdata*)lua_touserdata(L,index); /* get data */
|
usr=(swig_lua_userdata*)lua_touserdata(L,index); /* get data */
|
||||||
if (usr)
|
if (usr)
|
||||||
{
|
{
|
||||||
if (!type) /* special cast void*, no casting fn */
|
if (flags & SWIG_POINTER_DISOWN) /* must disown the object */
|
||||||
{
|
{
|
||||||
*ptr=usr->ptr;
|
usr->own=0;
|
||||||
return SWIG_OK; /* ok */
|
}
|
||||||
}
|
if (!type) /* special cast void*, no casting fn */
|
||||||
|
{
|
||||||
|
*ptr=usr->ptr;
|
||||||
|
return SWIG_OK; /* ok */
|
||||||
|
}
|
||||||
cast=SWIG_TypeCheckStruct(usr->type,type); /* performs normal type checking */
|
cast=SWIG_TypeCheckStruct(usr->type,type); /* performs normal type checking */
|
||||||
if (cast)
|
if (cast)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -120,14 +120,14 @@
|
||||||
// the checkfn SWIG_isptrtype will work for both userdata and nil's
|
// the checkfn SWIG_isptrtype will work for both userdata and nil's
|
||||||
%typemap(in,checkfn="SWIG_isptrtype") SWIGTYPE*,SWIGTYPE[]
|
%typemap(in,checkfn="SWIG_isptrtype") SWIGTYPE*,SWIGTYPE[]
|
||||||
%{
|
%{
|
||||||
if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&$1,$descriptor,0))){
|
if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&$1,$descriptor,$disown))){
|
||||||
SWIG_fail_ptr("$symname",$argnum,$descriptor);
|
SWIG_fail_ptr("$symname",$argnum,$descriptor);
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%typemap(in,checkfn="lua_isuserdata") SWIGTYPE&
|
%typemap(in,checkfn="lua_isuserdata") SWIGTYPE&
|
||||||
%{
|
%{
|
||||||
if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&$1,$descriptor,0))){
|
if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&$1,$descriptor,$disown))){
|
||||||
SWIG_fail_ptr("$symname",$argnum,$descriptor);
|
SWIG_fail_ptr("$symname",$argnum,$descriptor);
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|
@ -165,6 +165,17 @@
|
||||||
%{temp=($*ltype)SWIG_MustGetPtr(L,$input,$*descriptor,0,$argnum,"$symname");
|
%{temp=($*ltype)SWIG_MustGetPtr(L,$input,$*descriptor,0,$argnum,"$symname");
|
||||||
$1=&temp;%}
|
$1=&temp;%}
|
||||||
|
|
||||||
|
// DISOWN-ing typemaps
|
||||||
|
// if you have an object pointer which must be disowned, use this typemap
|
||||||
|
// eg. for void destroy_foo(Foo* toDie);
|
||||||
|
// use %apply SWIGTYPE* DISOWN {Foo* toDie};
|
||||||
|
// you could just use %delobject, but this is more flexible
|
||||||
|
%typemap(in,checkfn="SWIG_isptrtype") SWIGTYPE* DISOWN,SWIGTYPE DISOWN[]
|
||||||
|
%{ if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&$1,$descriptor,SWIG_POINTER_DISOWN))){
|
||||||
|
SWIG_fail_ptr("$symname",$argnum,$descriptor);
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
||||||
// Primitive types--return by value
|
// Primitive types--return by value
|
||||||
// must make a new object, copy the data & return the new object
|
// must make a new object, copy the data & return the new object
|
||||||
|
|
|
||||||
|
|
@ -450,7 +450,11 @@ public:
|
||||||
Replaceall(tm, "$target", ln);
|
Replaceall(tm, "$target", ln);
|
||||||
Replaceall(tm, "$input", source);
|
Replaceall(tm, "$input", source);
|
||||||
Setattr(p, "emit:input", source);
|
Setattr(p, "emit:input", source);
|
||||||
|
if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
|
||||||
|
Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
|
||||||
|
} else {
|
||||||
|
Replaceall(tm, "$disown", "0");
|
||||||
|
}
|
||||||
/* NEW LANGUAGE NOTE:***********************************************
|
/* NEW LANGUAGE NOTE:***********************************************
|
||||||
look for a 'checkfn' typemap
|
look for a 'checkfn' typemap
|
||||||
this an additional parameter added to the in typemap
|
this an additional parameter added to the in typemap
|
||||||
|
|
@ -1057,8 +1061,7 @@ public:
|
||||||
* ------------------------------------------------------------ */
|
* ------------------------------------------------------------ */
|
||||||
|
|
||||||
virtual int destructorHandler(Node *n) {
|
virtual int destructorHandler(Node *n) {
|
||||||
//have_destructor = 1;
|
//REPORT("destructorHandler", n);
|
||||||
//return SWIG_NOWRAP;
|
|
||||||
current = DESTRUCTOR;
|
current = DESTRUCTOR;
|
||||||
Language::destructorHandler(n);
|
Language::destructorHandler(n);
|
||||||
current = NO_CPP;
|
current = NO_CPP;
|
||||||
|
|
@ -1145,12 +1148,12 @@ public:
|
||||||
*/
|
*/
|
||||||
void EscapeCode(String* str)
|
void EscapeCode(String* str)
|
||||||
{
|
{
|
||||||
Printf(f_runtime,"/* original luacode:[[[\n%s\n]]]\n*/\n",str);
|
//Printf(f_runtime,"/* original luacode:[[[\n%s\n]]]\n*/\n",str);
|
||||||
Chop(str); // trim
|
Chop(str); // trim
|
||||||
Replace(str,"\\","\\\\",DOH_REPLACE_ANY); // \ to \\ (this must be done first)
|
Replace(str,"\\","\\\\",DOH_REPLACE_ANY); // \ to \\ (this must be done first)
|
||||||
Replace(str,"\"","\\\"",DOH_REPLACE_ANY); // " to \"
|
Replace(str,"\"","\\\"",DOH_REPLACE_ANY); // " to \"
|
||||||
Replace(str,"\n","\\n\"\n \"",DOH_REPLACE_ANY); // \n to \n"\n" (ie quoting every line)
|
Replace(str,"\n","\\n\"\n \"",DOH_REPLACE_ANY); // \n to \n"\n" (ie quoting every line)
|
||||||
Printf(f_runtime,"/* hacked luacode:[[[\n%s\n]]]\n*/\n",str);
|
//Printf(f_runtime,"/* hacked luacode:[[[\n%s\n]]]\n*/\n",str);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue