gpt4 book ai didi

lua - 简化Lua函数对C函数的调用

转载 作者:行者123 更新时间:2023-12-01 23:10:17 25 4
gpt4 key购买 nike

我是 Lua 新手

我有一个注册到 Lua 的 C 函数,如下所示:

call(obj, "func", param0, param1)

call()中:

  • 我们通过 C++ 中的自定义反射逻辑进行一些复杂的函数调度
  • obj(和所有参数)是固定的包装类型(类似于boost::any)

因此,我们无法使用常规 Lua 绑定(bind)工具(luabind、luabridge 等)进行简单的类成员注册

问题是:

我们怎样才能将Lua调用简化为这样:

obj.func(param0, param1)

obj:func(param0, param1)

谢谢。

最佳答案

您必须在您创建的每个obj上设置一个元表(假设它是您控制下的用户数据并且没有元表)并覆盖其中的__index元方法:

local cache = { }

debug.setmetatable(obj, {
__index = function (obj, k)
return function (obj, ...) -- or (...) for [non-canonical] .-syntax
return call(obj, k, ...)
end

-- malloc-optimized version --
local f = cache[k] or function (obj, ...) return call(obj, k, ...) end
cache[k] = f
return f
end,
__metatable = "whatever",
})

f = obj.func
f(obj, param0, param1) --> call(obj, 'func', param0, param1)

obj:func(param0, param1) --> the same via syntactic sugar

如果obj已经有一个元表,那么必须以类似的方式修改该元表。

同样可以通过 C 接口(interface)完成,因此您可以将 obj 创建与 __index 设置结合起来。

<小时/>

C端更新:

如果创建函数位于外部库中,那么除了捕获所有对象出现点(返回值和作为参数传递的表中的值)并按上述方式包装之外,您别无选择。

如果创建函数在您的控制之下,您可以在那里看到类似的内容:

ud = lua_newuserdata(L, sizeof(object));
*ud = object;

// this part is missing if objects have no metatable at all
luaL_getmetatable(L, tname); // or 'if (luaL_newmetatable(L, tname)) { ... }'
lua_setmetatable(L, -2);

return 1;

您必须在创建元表的位置添加 __index 元方法:

...代码中的某个位置,可能就在 *ud = object 行之后...

if (luaL_newmetatable(L, tname)) {
... original metatable setup ...

int res = luaL_loadstring(L,
"return function (obj, k)\n"
" return function (obj, ...)\n"
" return call(obj, k, ...)\n"
" end\n"
"end\n");
assert(res == 0);

lua_call(L, 0, 1);
lua_setfield(L, -2, "__index");
}

如果您的用户数据根本没有元表,则必须创建并设置它。

如果您想摆脱全局符号call,则将其 C 实现作为参数传递给 luaL_loadstring'ed block :

luaL_loadstring(L, "local call = ...\n return function (obj, k)\n" ...);
lua_pushcfunction(L, l_call);
lua_call(L, 1, 1); // instead of (0, 1)

然后 call 将本地化到闭包中。

关于lua - 简化Lua函数对C函数的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42652719/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com