Fixed issues with C++ classes and hierachies across multiple source files.

Fixed imports test case & added run test.
Added Examples/imports.
Added typename for raw lua_State*
Added documentation on native functions.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9748 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Mark Gossage 2007-05-02 02:20:29 +00:00
commit 61fdde65cc
19 changed files with 820 additions and 481 deletions

View file

@ -1,6 +1,13 @@
Version 1.3.32 (in progress) Version 1.3.32 (in progress)
============================ ============================
05/02/2007: mgossage
[Lua] Fixed issues with C++ classes and hierachies across multiple
source files. Fixed imports test case & added run test.
Added Examples/imports.
Added typename for raw lua_State*
Added documentation on native functions.
05/07/2007: gga 05/07/2007: gga
[Ruby] [Ruby]
Docstrings are now supported. Docstrings are now supported.

View file

@ -33,12 +33,13 @@
<li><a href="#Lua_nn19">Class extension with %extend</a> <li><a href="#Lua_nn19">Class extension with %extend</a>
<li><a href="#Lua_nn20">C++ templates</a> <li><a href="#Lua_nn20">C++ templates</a>
<li><a href="#Lua_nn21">C++ Smart Pointers</a> <li><a href="#Lua_nn21">C++ Smart Pointers</a>
<li><a href="#Lua_nn22">Writing your own custom wrappers</a>
</ul> </ul>
<li><a href="#Lua_nn22">Details on the Lua binding</a> <li><a href="#Lua_nn23">Details on the Lua binding</a>
<ul> <ul>
<li><a href="#Lua_nn23">Binding global data into the module.</a> <li><a href="#Lua_nn24">Binding global data into the module.</a>
<li><a href="#Lua_nn24">Userdata and Metatables</a> <li><a href="#Lua_nn25">Userdata and Metatables</a>
<li><a href="#Lua_nn25">Memory management</a> <li><a href="#Lua_nn26">Memory management</a>
</ul> </ul>
</ul> </ul>
</div> </div>
@ -952,7 +953,24 @@ If you ever need to access the underlying pointer returned by <tt>operator-&gt;(
&gt; f = p:__deref__() -- Returns underlying Foo * &gt; f = p:__deref__() -- Returns underlying Foo *
</pre></div> </pre></div>
<H2><a name="Lua_nn22"></a>22.4 Details on the Lua binding</H2> <H3><a name="Lua_nn22"></a>22.3.15 Writing your own custom wrappers</H3>
<p>
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:
</p>
<div class="code"><pre>%native(my_func) int native_function(lua_State*L); // registers it with SWIG
...
%{
int native_function(lua_State*L) // my native code
{
...
}
%}
</pre></div>
<p>
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.
</p>
<H2><a name="Lua_nn23"></a>22.4 Details on the Lua binding</H2>
<p> <p>
@ -963,7 +981,7 @@ If you ever need to access the underlying pointer returned by <tt>operator-&gt;(
</i> </i>
</p> </p>
<H3><a name="Lua_nn23"></a>22.4.1 Binding global data into the module.</H3> <H3><a name="Lua_nn24"></a>22.4.1 Binding global data into the module.</H3>
<p> <p>
@ -1023,7 +1041,7 @@ end
<p> <p>
That way when you call '<tt>a=example.Foo</tt>', 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 '<tt>example.Foo=10</tt>', 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)'. That way when you call '<tt>a=example.Foo</tt>', 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 '<tt>example.Foo=10</tt>', 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)'.
</p> </p>
<H3><a name="Lua_nn24"></a>22.4.2 Userdata and Metatables</H3> <H3><a name="Lua_nn25"></a>22.4.2 Userdata and Metatables</H3>
<p> <p>
@ -1103,7 +1121,7 @@ Note: Both the opaque structures (like the FILE*) and normal wrappered classes/s
<p> <p>
Note: Operator overloads are basically done in the same way, by adding functions such as '__add' &amp; '__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. Note: Operator overloads are basically done in the same way, by adding functions such as '__add' &amp; '__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.
</p> </p>
<H3><a name="Lua_nn25"></a>22.4.3 Memory management</H3> <H3><a name="Lua_nn26"></a>22.4.3 Memory management</H3>
<p> <p>

View file

@ -4,6 +4,7 @@ constants
funcptr3 funcptr3
functest functest
functor functor
import
pointer pointer
simple simple
variables variables

View file

@ -0,0 +1,19 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
SWIGOPT =
LIBS =
all::
$(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \
LIBS='$(LIBS)' TARGET='base' INTERFACE='base.i' lua_cpp
$(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \
LIBS='$(LIBS)' TARGET='foo' INTERFACE='foo.i' lua_cpp
$(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \
LIBS='$(LIBS)' TARGET='bar' INTERFACE='bar.i' lua_cpp
$(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \
LIBS='$(LIBS)' TARGET='spam' INTERFACE='spam.i' lua_cpp
clean::
$(MAKE) -f $(TOP)/Makefile lua_clean
check: all

View file

@ -0,0 +1,36 @@
This example tests the %import directive and working with multiple modules.
Use 'lua runme.lua' 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:
--------
Sorry, no files here.
If you know how, you could copy the python or ruby example dsw & dsp and try editing that

21
Examples/lua/import/bar.h Normal file
View file

@ -0,0 +1,21 @@
#include "base.h"
class Bar : public Base {
public:
Bar() { }
~Bar() { }
virtual const char * A() const {
return "Bar::A";
}
const char * B() const {
return "Bar::B";
}
virtual Base *toBase() {
return static_cast<Base *>(this);
}
static Bar *fromBase(Base *b) {
return dynamic_cast<Bar *>(b);
}
};

View file

@ -0,0 +1,9 @@
%module bar
%{
#include "bar.h"
%}
%import base.i
%include "bar.h"

View file

@ -0,0 +1,16 @@
class Base {
public:
Base() { };
virtual ~Base() { };
virtual const char * A() const {
return "Base::A";
}
const char * B() const {
return "Base::B";
}
virtual Base *toBase() {
return static_cast<Base *>(this);
}
};

View file

@ -0,0 +1,6 @@
%module base
%{
#include "base.h"
%}
%include base.h

21
Examples/lua/import/foo.h Normal file
View file

@ -0,0 +1,21 @@
#include "base.h"
class Foo : public Base {
public:
Foo() { }
~Foo() { }
virtual const char * A() const {
return "Foo::A";
}
const char * B() const {
return "Foo::B";
}
virtual Base *toBase() {
return static_cast<Base *>(this);
}
static Foo *fromBase(Base *b) {
return dynamic_cast<Foo *>(b);
}
};

View file

@ -0,0 +1,8 @@
%module foo
%{
#include "foo.h"
%}
%import base.i
%include "foo.h"

View file

@ -0,0 +1,103 @@
# Test various properties of classes defined in separate modules
print("Testing the %import directive")
if string.sub(_VERSION,1,7)=='Lua 5.0' then
-- lua5.0 doesnt have a nice way to do this
function loadit(a,b)
lib=loadlib(a..':dll',b) or loadlib(a..':so',b)
assert(lib)()
end
loadit('base','Base_Init')
loadit('foo','Foo_Init')
loadit('bar','Bar_Init')
loadit('spam','Spam_Init')
else
-- lua 5.1 does
require 'base'
require 'foo'
require 'bar'
require 'spam'
end
-- 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("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")
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 then
print "bad swig"
else
print "good swig"
end
print " Spam -> Base -> Bar : "
y = bar.Bar_fromBase(x)
if y then
print "good swig"
else
print "bad swig"
end
print " Spam -> Base -> Spam : "
y = spam.Spam_fromBase(x)
if y then
print "good swig"
else
print "bad swig"
end
print " Foo -> Spam : "
y = spam.Spam_fromBase(b)
if y then
print "bad swig"
else
print "good swig"
end

View file

@ -0,0 +1,24 @@
#include "bar.h"
class Spam : public Bar {
public:
Spam() { }
~Spam() { }
virtual const char * A() const {
return "Spam::A";
}
const char * B() const {
return "Spam::B";
}
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);
}
};

View file

@ -0,0 +1,9 @@
%module spam
%{
#include "spam.h"
%}
%import bar.i
%include "spam.h"

View file

@ -0,0 +1,28 @@
require("import") -- the import fn
-- need to load two modules
import("imports_a") -- import code
import("imports_b") -- import code
b=imports_b.B()
b:hello() -- call member function in A which is in a different SWIG generated library.
b:bye()
assert (b:member_virtual_test(imports_a.A_memberenum1) == imports_a.A_memberenum2)
assert (b:global_virtual_test(imports_a.globalenum1) == imports_a.globalenum2)
imports_b.global_test(imports_a.A_memberenum1)
--[[ B b = new B();
b.hello(); //call member function in A which is in a different SWIG generated library.
B b = new B();
b.hello(); //call member function in A which is in a different SWIG generated library.
b.bye();
if (b.member_virtual_test(A.MemberEnum.memberenum1) != A.MemberEnum.memberenum2)
throw new Exception("Test 1 failed");
if (b.global_virtual_test(GlobalEnum.globalenum1) != GlobalEnum.globalenum2)
throw new Exception("Test 2 failed");
imports_b.global_test(A.MemberEnum.memberenum1);
]]

View file

@ -65,6 +65,7 @@ typedef struct swig_lua_class {
swig_lua_method *methods; swig_lua_method *methods;
swig_lua_attribute *attributes; swig_lua_attribute *attributes;
struct swig_lua_class **bases; struct swig_lua_class **bases;
char **base_names;
} swig_lua_class; } swig_lua_class;
/* this is the struct for wrappering all pointers in SwigLua /* this is the struct for wrappering all pointers in SwigLua
@ -128,6 +129,26 @@ it gets the address, casts it, then dereferences it */
//#define SWIG_mem_fn_as_voidptr(a) (*((char**)&(a))) //#define SWIG_mem_fn_as_voidptr(a) (*((char**)&(a)))
#endif #endif
/* storing/access of swig_module_info */
SWIGRUNTIME swig_module_info *
SWIG_Lua_GetModule(lua_State* L) {
swig_module_info *ret = 0;
lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME);
lua_rawget(L,LUA_REGISTRYINDEX);
if (lua_islightuserdata(L,-1))
ret=(swig_module_info*)lua_touserdata(L,-1);
lua_pop(L,1); /* tidy */
return ret;
}
SWIGRUNTIME void
SWIG_Lua_SetModule(lua_State* L, swig_module_info *module) {
/* add this all into the Lua registry: */
lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME);
lua_pushlightuserdata(L,(void*)module);
lua_rawset(L,LUA_REGISTRYINDEX);
}
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* global variable support code: modules * global variable support code: modules
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
@ -466,6 +487,7 @@ SWIGINTERN void SWIG_Lua_add_class_details(lua_State* L,swig_lua_class* clss)
/* performs the entire class registration process */ /* performs the entire class registration process */
SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss) SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss)
{ {
int i;
/* add its constructor to module with the name of the class /* add its constructor to module with the name of the class
so you can do MyClass(...) as well as new_MyClass(...) so you can do MyClass(...) as well as new_MyClass(...)
BUT only if a constructor is defined BUT only if a constructor is defined
@ -500,6 +522,20 @@ SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss)
lua_rawset(L,-3); /* metatable into registry */ lua_rawset(L,-3); /* metatable into registry */
lua_pop(L,1); /* tidy stack (remove registry) */ lua_pop(L,1); /* tidy stack (remove registry) */
/* set up the class base classes
we need to check the names of the classes to see if the base class exists
if so, we need to set up the pointer to it */
swig_module_info* module=SWIG_GetModule(L);
for(i=0;clss->base_names[i];i++)
{
if (clss->bases[i]==0) /* not found yet */
{
/* lookup and cache the base class */
swig_type_info *info = SWIG_TypeQueryModule(module,module,clss->base_names[i]);
if (info) clss->bases[i] = (swig_lua_class *) info->clientdata;
}
}
SWIG_Lua_get_class_metatable(L,clss->name); SWIG_Lua_get_class_metatable(L,clss->name);
SWIG_Lua_add_class_details(L,clss); /* recursive adding of details (atts & ops) */ SWIG_Lua_add_class_details(L,clss); /* recursive adding of details (atts & ops) */
lua_pop(L,1); /* tidy stack (remove class metatable) */ lua_pop(L,1); /* tidy stack (remove class metatable) */
@ -593,7 +629,6 @@ SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State* L,void* ptr,size_t size,swig_t
SWIGRUNTIME int SWIG_Lua_ConvertPacked(lua_State* L,int index,void* ptr,size_t size,swig_type_info *type) SWIGRUNTIME int SWIG_Lua_ConvertPacked(lua_State* L,int index,void* ptr,size_t size,swig_type_info *type)
{ {
swig_lua_rawdata* raw; swig_lua_rawdata* raw;
swig_cast_info *cast;
raw=(swig_lua_rawdata*)lua_touserdata(L,index); /* get data */ raw=(swig_lua_rawdata*)lua_touserdata(L,index); /* get data */
if (!raw) return SWIG_ERROR; /* error */ if (!raw) return SWIG_ERROR; /* error */
if (type==0 || type==raw->type) /* void* or identical type */ if (type==0 || type==raw->type) /* void* or identical type */
@ -678,26 +713,6 @@ SWIG_Lua_InstallConstants(lua_State* L, swig_lua_const_info constants[]) {
} }
} }
/* storing/access of swig_module_info */
SWIGRUNTIME swig_module_info *
SWIG_Lua_GetModule(lua_State* L) {
swig_module_info *ret = 0;
lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME);
lua_rawget(L,LUA_REGISTRYINDEX);
if (lua_islightuserdata(L,-1))
ret=(swig_module_info*)lua_touserdata(L,-1);
lua_pop(L,1); /* tidy */
return ret;
}
SWIGRUNTIME void
SWIG_Lua_SetModule(lua_State* L, swig_module_info *module) {
/* add this all into the Lua registry: */
lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME);
lua_pushlightuserdata(L,(void*)module);
lua_rawset(L,LUA_REGISTRYINDEX);
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -197,6 +197,13 @@ with the relevant operators.
%typemap(out) long long, unsigned long long, signed long long %typemap(out) long long, unsigned long long, signed long long
%{ lua_pushnumber(L, (lua_Number) $1); SWIG_arg++;%} %{ lua_pushnumber(L, (lua_Number) $1); SWIG_arg++;%}
/* It is possible to also pass a lua_State* into a function, so
void fn(int a, float b, lua_State* s) is wrappable as
> fn(1,4.3) -- note: the state is implicitly passed in
*/
%typemap(in, numinputs=0) lua_State*
%{$1 = L;%}
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* typecheck rules * typecheck rules
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */

View file

@ -583,6 +583,7 @@ NEW LANGUAGE NOTE:END ************************************************/
/* Close the function */ /* Close the function */
Printv(f->code, "return SWIG_arg;\n", NIL); Printv(f->code, "return SWIG_arg;\n", NIL);
// add the failure cleanup code: // add the failure cleanup code:
Printv(f->code, "\nif(0) SWIG_fail;\n", NIL);
Printv(f->code, "\nfail:\n", NIL); Printv(f->code, "\nfail:\n", NIL);
Printv(f->code, "$cleanup", "lua_error(L);\n", NIL); Printv(f->code, "$cleanup", "lua_error(L);\n", NIL);
Printv(f->code, "return SWIG_arg;\n", NIL); Printv(f->code, "return SWIG_arg;\n", NIL);
@ -891,8 +892,16 @@ NEW LANGUAGE NOTE:END ************************************************/
Delete(s_attr_tab); Delete(s_attr_tab);
// Handle inheritance // Handle inheritance
// note: with the idea of class hireachied spread over mutliple modules
// cf test-suite: imports.i
// it is not possible to just add the pointers to the base classes to the code
// (as sometimes these classes are not present)
// therefore we instead hold the name of the base class and a null pointer
// at runtime: we can query the swig type manager & see if the class exists
// if so, we can get the pointer to the base class & replace the null pointer
// if the type does not exist, then we cannot...
String *base_class = NewString(""); String *base_class = NewString("");
String *base_class_names = NewString("");
List *baselist = Getattr(n, "bases"); List *baselist = Getattr(n, "bases");
if (baselist && Len(baselist)) { if (baselist && Len(baselist)) {
@ -905,44 +914,24 @@ NEW LANGUAGE NOTE:END ************************************************/
b = Next(b); b = Next(b);
continue; continue;
} }
/* if( itcl ) { // old code: (used the pointer to the base class)
have_base_classes = 1; //String *bmangle = Swig_name_mangle(bname);
Printv( base_classes, bname, " ", NIL ); //Printf(base_class, "&_wrap_class_%s", bmangle);
Printv( base_class_init , " ", bname, "Ptr::constructor $ptr\n", NIL ); //Putc(',', base_class);
}*/ //Delete(bmangle);
String *bmangle = Swig_name_mangle(bname); // new code: stores a null pointer & the name
// Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL); Printf(base_class, "0,");
Printf(base_class, "&_wrap_class_%s", bmangle); Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname));
// Put code to register base classes in init function
// Printf(f_init,"/* Register base : %s */\n", bmangle);
// Printf(f_init,"swig_%s_bases[%d] = (swig_class *) SWIG_TypeQuery(\"%s *\")->clientdata;\n", mangled_classname, index, SwigType_namestr(bname));
b = Next(b); b = Next(b);
index++; index++;
Putc(',', base_class);
Delete(bmangle);
} }
} }
/* List *baselist = Getattr(n,"bases");
if (baselist && Len(baselist)) {
Node *base = First(baselist);
while (base) {
String *bname = Getattr(base, "name");
if ((!bname) || GetFlag(base,"feature:ignore") || (!Getattr(base,"module"))) {
base = Next(baselist);
continue;
}
String *bmangle = Swig_name_mangle(bname);
Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL);
Printf(base_class,"&_wrap_class_%s",bmangle);
base = Next(baselist);
Putc(',',base_class);
Delete(bmangle);
}
}*/
Printv(f_wrappers, "static swig_lua_class *swig_", mangled_classname, "_bases[] = {", base_class, "0};\n", NIL); Printv(f_wrappers, "static swig_lua_class *swig_", mangled_classname, "_bases[] = {", base_class, "0};\n", NIL);
Delete(base_class); Delete(base_class);
Printv(f_wrappers, "static char *swig_", mangled_classname, "_base_names[] = {", base_class_names, "0};\n", NIL);
Delete(base_class_names);
Printv(f_wrappers, "swig_lua_class _wrap_class_", mangled_classname, " = { \"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL); Printv(f_wrappers, "swig_lua_class _wrap_class_", mangled_classname, " = { \"", class_name, "\", &SWIGTYPE", SwigType_manglestr(t), ",", NIL);
@ -959,7 +948,9 @@ NEW LANGUAGE NOTE:END ************************************************/
} else { } else {
Printf(f_wrappers, ",0"); Printf(f_wrappers, ",0");
} }
Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname, "_bases };\n\n", NIL); Printf(f_wrappers, ", swig_%s_methods, swig_%s_attributes, swig_%s_bases, swig_%s_base_names };\n\n", mangled_classname, mangled_classname, mangled_classname, mangled_classname);
// Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname, "_bases };\n\n", NIL);
// Printv(s_cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, &_wrap_class_", mangled_classname, "},\n", NIL); // Printv(s_cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, &_wrap_class_", mangled_classname, "},\n", NIL);
Delete(t); Delete(t);
Delete(mangled_classname); Delete(mangled_classname);