我正在使用Lua API for C / C ++在C / C ++中创建函数,然后注册它们以在Lua脚本中使用。显然,这些函数期望使用特定类型的一定数量的参数,这在C / C ++中没有问题,因为静态类型化。但是,鉴于Lua是动态的,因此当我从Lua调用此C函数时,我需要手动检查传递的参数数量及其类型。这些参数被压入Lua堆栈,因此我可以使用lua_gettop
检查参数的数量,然后使用lua_type
检查参数的类型。
我的问题是,能否保证堆栈中元素的数量,即传递给函数的参数的数量?这样,我可以在C函数的开头声明以下内容:assert(lua_gettop(L) == x)
,其中x
只是所需数量的参数的占位符,而L
是{ {1}}。这进一步扩展了一点,因为我想知道与Lua堆栈交互的其他函数是否可以清除,以使在我调用此函数时堆栈为空。否则,如果以前的函数调用将某些内容留在堆栈上,则断言将失败。下面是一个简单的示例。
C / C ++代码:
lua_State*
在Lua中调用该函数。假设函数期望两个字符串作为参数;因此,第一个调用将成功,第二个调用将失败。
int foo(lua_State* L) {
assert(lua_gettop(L) == 2);
// do stuff
return 1;
}
答案 0 :(得分:3)
如果您直接向Lua注册了一个函数,并且Lua脚本使用N个参数调用该函数,则该函数在被调用时将在堆栈上具有N个值。这就是它的工作方式,并且没有任何进程可以对此进行干预(嗯,您可以手动使用不正确的lua_State
从C调用该函数,但这是您的错)。
只要您在该函数的开始与检查当前堆栈大小的操作之间不进行任何堆栈操作,您的测试就将是准确的。
每个Lua函数在如何(或是否)操纵堆栈方面都有详尽的文档。是否将值插入堆栈,从堆栈中删除值,等等。
话虽这么说,assert
可能是错误的工具。如果用户提供了错误数量的参数,并且您认为该错误行为,则应调用lua_error
。而不仅仅是在调试版本上。