SWIG Lua:用%native扩展(%extend)类.是否可以添加%native方法
SWIG Lua: Extending (%extend) class with %native. Is it possible to add %native method?
%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 addedn", 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函数,您希望将其用作userdata的方法:
%{
int function(lua_State *L)
{
printf("Method called!n");
return 0;
}
%}
我几乎刚刚弄明白了,我想把它贴在这里,因为这个页面在谷歌排名很高,这是一个相当不错的解决方案来完成工作。这需要在您使用SWIG编写的每个包装器绑定(*.i)文件中完成。
祝你好运!
Lua没有任何真正的方法概念,只是一些带有语法糖的函数表,因此您可以编写看起来相当OO' s的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
}
...
%}
% lucode使Bar作为Foo"类"的一部分可用,尽管我在这方面有点生手,但您可能必须将Bar添加到Foo元表中,或者从C中完成(请参阅SWIG用户指南的第5.6节,了解您可以尝试这样做的. I文件的部分)。
很想知道这是否有效。
相关文章:
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 此代码是否违反一个定义规则
- 是否需要删除包含对象的"pair"?
- 是否可以从int转换为enum类类型
- 无论条件是否为true,if总是在c++中执行
- 如何找到大小'x'数组是否完全填充,在C++?
- 检查值是否在集合p1和p2中,但不在p3中
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- Native Client模块是否可以呈现由C++代码生成的HTML
- SWIG Lua:用%native扩展(%extend)类.是否可以添加%native方法