Lua C API 如何确定函数是作为 class 成员调用的还是只是来自 table 的函数?

Lua C API How to determine were function called as class member or just function from table?

我有一个使用 Lua C API 的 C++ 应用程序。 我通过 lua api:

声明了全局 table
lua_newtable(L);

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

lua_setglobal(L, "table1");

现在我可以使用“.”调用一些LuaFunc或 ':'

table1.someLuaFunc()
table1:someLuaFunc()

这两种情况都会 运行 someCFunc。

问题是:在 someCFunc 内部,是否有任何方法可以确定它是如何被调用的(通过 : 或 .)?

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

不,你不能。

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 在这种情况下的范例是鸭子类型。没有明显的类型,无论如何只有 table(或用户信息),所以只需检查您的论点是否有必要 data/methods 您想要 process/call 如果没有则拒绝。

我可能不会依赖它,但是 Lua 的调试库可以解决这个问题(通过在字节码中查找 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() and lua_getinfo().