有没有办法以编程方式确定在C / C ++中Lua函数需要多少个参数?

时间:2009-04-24 09:43:40

标签: c++ lua

有没有办法确定Lua函数在从C / C ++代码调用它之前需要多少参数?

我查看了lua_Debuglua_getinfo,但它们似乎没有提供我需要的内容。

看起来有点像我反对Lua的精神,但我真的想要证明我在Lua和C ++之间的接口。当从Lua代码调用C ++函数时,接口验证Lua提供了正确数量的参数,并且每个参数的类型都是正确的。如果在参数中发现问题,则发出lua_error

我想要反过来检查类似的错误。当C ++调用Lua函数时,它至少应检查Lua函数是否没有声明更多参数。

5 个答案:

答案 0 :(得分:5)

Lua无法满足您的要求。

您可以使用一组参数定义Lua函数,如下所示:

function f(a, b, c)
   body
end

但是,Lua对传递给此函数的参数数量没有限制。

这是有效的:

f(1,2,3,4,5)

忽略额外的参数。

这也是有效的:

f(1)

其余参数分配为'nil'。

最后,您可以定义一个带有可变数量参数的函数:

function f(a, ...)

此时你可以向函数传递任意数量的参数。

请参阅Lua reference manual的第2.5.9节。

您可以在此处做的最好的事情是将检查添加到您的Lua函数中,以验证您是否收到了您期望的参数。

答案 1 :(得分:4)

您可以使用'u'类型填充nups, nparams, isvararg fields by get_info()来确定参数的数量,upvalues以及函数是否接受Lua 5.2中可变数量的参数。 Lua 5.1中没有此功能。

答案 2 :(得分:2)

除非你完全控制你正在验证的Lua代码,否则我不会在Lua方面这样做。 Lua函数通过省略它们来忽略额外的参数是相当普遍的。

一个例子是我们不想实现某些方法,并使用存根函数:

function do_nothing() end

full_api = {}
function full_api:callback(a1, a2) print(a1, a2) end

lazy_impl = {}
lazy_impl.callback = do_nothing

这样可以通过重用可用的功能来节省打字(和一点性能)。

如果您仍想进行函数参数验证,则必须静态分析代码。执行此操作的一个工具是Metalua

答案 3 :(得分:1)

不,不在标准的Lua范围内。 Aaron Saarela是在说,根据我的理解,它有点超出了Lua的精神。 Lua的方法是确保函数本身将nil视为合理的默认值(或在第一次使用之前将其转换为合理的默认值,如name = name or "Bruce")或者没有合理的默认值该函数应该抛出错误或返回失败(if not name then error"Name required" end是前者的常用习语,if not name then return nil, "name required" end是后者的常用习语。通过让Lua一方负责自己的参数检查,无论是从Lua还是C调用该函数,都可以获得该优势。

也就是说,您的模块可能会维护一个由包含您需要知道的信息的函数索引的属性表。当然,这需要维护。 MetaLua也可以用于添加一些语法糖,以便在编译时直接从函数声明创建表。在调用Lua函数之前,您可以直接使用它来查找任何可用的属性并使用它们来验证调用。

如果您担心防弹,您可能希望控制功能环境以使用Lua端可用的全局(如果有)全局变量,并使用lua_pcall()而不是{{1这样你就可以捕获任何抛出的错误。

答案 4 :(得分:1)

您要求的信息并非在所有情况下都可用。例如,Lua函数实际上可能在C中实现为lua_CFunction。从Lua代码中无法区分纯Lua函数和lua_CFunction。在lua_CFunction的情况下,参数的数量根本没有公开,因为它完全取决于函数的实现方式。

另一方面,你可以做的是为函数编写者提供一个系统(无论是纯粹的Lua还是C语言)来宣传他们的函数所期望的参数数量。在创建函数(函数f(a,b,c)结束)之后,它们只是将它传递给全局函数(寄存器(f,3))。然后,您就可以从C ++代码中检索该信息,如果该函数没有公布其参数,则回退到您现在拥有的信息。使用这样的系统,您甚至可以通过参数宣传预期的类型。