Lua C API如何确定函数是作为类成员调用还是从表中调用的?

3

我有一个使用Lua C API的C++应用程序。 我通过Lua API声明了一个全局表:

lua_newtable(L);

lua_pushstring(L, "someLuaFunc");
lua_pushcfunction(L, &someCFunc);
lua_settable(L, -3);

lua_setglobal(L, "table1");

现在我可以使用 '.' 或 ':' 调用一些Lua函数。
table1.someLuaFunc()
table1:someLuaFunc()

两种情况都将运行someCFunc。

问题是:在someCFunc内部,有没有办法确定它是如何被调用的(通过“:”还是“.”)?

在我的情况下,检查参数计数和类型不是一种选择。


1
如果您能明确您的目标,即为什么不能检查参数数量或类型(这是显而易见的方法),那么也许有人可以提供更进一步的帮助。 - Ctx
2个回答

2
不可以。
object:method()

被直接翻译成

main <123.lua:0,0> (4 instructions, 16 bytes at 00020510)
0+ params, 2 slots, 0 upvalues, 0 locals, 2 constants, 0 functions
        1       [1]     GETGLOBAL       0 -1    ; object
        2       [1]     SELF            0 0 -2  ; "method"
        3       [1]     CALL            0 2 1

那就是说,SELF 操作码将函数放在寄存器中,并将其紧密排列在调用对象附近,然后 CALL 操作码执行常规调用。
Lua 在这种情况下的范例是鸭子类型。没有明确的类型,只有表格(或用户信息),因此只需检查您的参数是否具有要处理/调用的必要数据/方法,并在其不具备时拒绝使用。

有没有可能用纯Lua获取这些指令?(例如GetInstructions(func)?)如果可以,你会怎么做? - warspyking
@warspyking,可以和不可以。您可以使用string.dump来获取操作码转储,但是除了将其loadstring回来之外,它的用法没有任何支持,因此您需要自己解析它。 - Oleg V. Volkov
实际上,还有@lhf的字节码检查器库[lbci](http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lbci)(也可通过LuaRocks获得)。 - siffiejoe
@Oleg 当我逐个打印出string.dump的字符时,我没有得到指令,我错过了什么? - warspyking

2

我可能不会完全依赖它,但Lua的debug库可以找出这个问题(通过查找字节码中的OP_SELF操作码)。在Lua中:

local t = {}
function t:f()
  print( debug.getinfo( 1, "n" ).namewhat )
end

t.f( t ) --> prints "field"
t:f()    --> prints "method"

在 C 语言中,你需要使用 lua_getstack()lua_getinfo()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接