%module test
class Foo{
public:
Foo();
}
我想要这样的东西:
%extend Foo{
%native(Bar) int Bar(lua_State * L);
}
在绑定的 .i 文件中,最后包含以下代码:
%wrapper %{
// This is code to add a new function to the object's metatable
void script_addNativeMethod(lua_State *L, const char *className, const char *methodName, lua_CFunction fn)
{
SWIG_Lua_get_class_registry(L); /* get the registry */
lua_pushstring(L, className); /* get the name */
lua_rawget(L,-2); /* get the metatable itself */
lua_remove(L,-2); /* tidy up (remove registry) */
// If the metatable is not null, add the method to the ".fn" table
if(lua_isnil(L, -1) != 1)
{
SWIG_Lua_get_table(L, ".fn");
SWIG_Lua_add_function(L, methodName, fn);
lua_pop(L, 2); /* tidy up (remove metatable and ".fn" table) */
}
else
{
printf("[script_addNativeMethod(..)] - \"%s\" metatable is not found. Method \"%s\" will not be added\n", className, methodName);
return;
}
}
%}
它的作用是向包装 CPP 文件中添加一个名为“script_addNativeMethod”的新函数。您可以在“init”绑定代码中调用此函数,如下所示:
// Wrapper to add native Lua methods to existing C++ classes
%init %{
script_addNativeMethod(L, "MetatableName", "methodName", /*int function(lua_State *L)*/function);
%}
最重要的是,在绑定文件中,您需要具有要用作用户数据方法的实际本机 lua 函数:
%{
int function(lua_State *L)
{
printf("Method called!\n");
return 0;
}
%}
我实际上只是想通了这一点,我想在这里发布它,因为这个页面在谷歌中排名很高,这是完成工作的一个相当不错的解决方案。这需要在您使用 SWIG 编写的每个包装器绑定 (*.i) 文件中完成。
祝你好运!
Lua 没有任何真正的方法概念,只有带有一些语法糖的函数表,因此您可以编写看起来非常 OO'ish 的 Lua 代码:
foo = test.Foo() # will call the C++ Foo constructor and return a wrapped (Lua) Foo
myInt = foo:Bar()
当你写
myInt = foo:Bar()
Lua实际上是在执行
myInt = foo.Bar(foo)
这将导致 Lua 在 foo 元表中查找名为 Bar 的函数,并将 foo 实例作为第一个参数。因此,您需要做的更多的是遵循以下伪代码(未经测试,可能存在语法错误,参数顺序错误等,但希望您能理解):
%native(Bar) int Bar(lua_State * L);
%{
int Bar(lua_State*L) {
// there should be one arg on the stack: the Foo instance
Foo* foo = (Foo*)<get void* from L stack>
int answer = foo.Bar();
// push answer onto L stack
lua_pushnumber(L, answer);
return 1;
}
%}
%luacode {
test.Foo.Bar = test.Bar
}
...
%}
%luacode 使 Bar 作为 Foo “类”的一部分可用,尽管我在该领域有点生疏,但您可能必须将 Bar 添加到 Foo 元表中,或者从 C 中执行(参见 SWIG 用户的第 5.6 节.i 文件部分的指南,您可以在其中尝试执行此操作)。
很想知道这是否有效。