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

我有一个使用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");

现在我可以使用“.”或“:”调用someLuaFunc。这两种情况下都会运行someCFunc。

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

在我的情况下,检查参数数量和类型不是一个选项。

点赞
用户936986
用户936986

不,你不能。

object:method()

被直接翻译为

main <123.lua:0,0> (4条指令,16个字节,位于 00020510)
0+ 参数,2个槽,0个上值,0个局部变量,2个常量,0个函数
        1       [1]     GETGLOBAL       0 -1    ; object
        2       [1]     SELF            0 0 -2  ; "method"
        3       [1]     CALL            0 2 1

也就是说,SELF 操作码会把函数放在调用对象的寄存器附近,然后 CALL 操作码执行常规调用。

在这种情况下,Lua 的编程范式是鸭子类型。没有明显的类型,只有表格(或用户信息),因此只需检查您的参数是否具有想要处理/调用的必要数据/方法,并在不具备这些数据/方法时拒绝。

2015-12-14 11:52:45
用户3677376
用户3677376

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

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

t.f(t) --> 打印 "field"
t:f()  --> 打印 "method"

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

2015-12-14 18:10:31