我有一个应用程序使用lua文件来处理一些比较模糊的配置选项。因此,它主要包含对应用程序的调用以创建内容并更改属性;大多数C函数没有返回值,但有些函数没有。
我现在需要将这些相同的配置文件读入不同的应用程序,并在调用函数时执行显着不同的操作(因此我无法使用公共代码)。另外,我只对可能的函数的子集感兴趣,并且我认为我可以默认忽略(和/或返回nil)任何其他函数调用。
所以我想知道这里最好的方法是什么。如何(从C ++应用程序),我可以加载和执行lua脚本,使表达式等被评估为正常但我可以拦截和处理某些应用程序定义的C函数,同时只是忽略(如果需要,返回nil)调用任何其他C功能
(注意:我确实可以访问原始应用程序的词汇表,主要使用luabind;我可以使用相同的定义并更改实现,但这太脆弱了,因为原始应用程序可以添加更多功能后来。我想要更通用的东西。)
目标是获得一些C代码,我可以将其用作通用占位符;最终结果是“任何已定义的内容(标准库例程,Lua中定义的函数和C函数明确注册),将其称为正常;对于其他任何事情,调用一个不执行任何操作的特定例程,而不是引发错误”。最好是与luabind兼容的东西。
整个过程由一些C代码启动,这些代码设置Lua环境,加载一组文件,调用一个函数,然后破坏环境。没有任何进展。
答案 0 :(得分:4)
为nil设置__call元方法:
debug.setmetatable(nil, { __call=function () end })
_G或其他表的_index元方法不起作用,因为在调用之前名称已解析。
(如果您从C设置它,则无需使用调试API或库。)
答案 1 :(得分:3)
如何使用setfenv和metatable?您可以使用空表替换某些函数的全局环境表。然后,设置占位符函数以忽略C定义的函数。
local env = {} -- empty environment
local metatbl = {}
function metatbl.__index (tbl, key) -- provides placeholder function
return function()
print(key .. " called")
return(nil)
end
end
setmetatable(env, metatbl)
function samplefunc() -- your Lua code goes here
globalfunction "xyz" -- calls placeholder function
end
setfenv(samplefunc, env)
samplefunc()
如果你想使用print
这样的内置函数,可以将其推送到env talbe中,如:
local env = {print = print}
答案 2 :(得分:0)
如果您有某种方法可以将C函数与脚本中的普通Lua函数区分开来,则可以迭代Lua系统中定义的所有函数,以及不在您关注的函数列表中的每个C函数关于,用一个简单的nil返回函数替换该函数的实现。如果所有c-binding函数在表中整齐定义,这非常容易;如果他们在_G
,你就会有一点工作。您做关心的功能正常通过luabind绑定。