【问题标题】:Lua C API How to determine were function called as class member or just function from table?Lua C API如何确定函数是作为类成员调用还是只是表中的函数?
【发布时间】:2016-03-19 21:01:08
【问题描述】:

我有使用 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或':'

table1.someLuaFunc()
table1:someLuaFunc()

两种情况都会运行 someCFunc。

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

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

【问题讨论】:

  • 如果你指定你想要达到的目标,也许有人可以提供进一步的帮助,即为什么不能检查参数计数或类型,这将是显而易见的方式

标签: c++ c lua lua-api


【解决方案1】:

不,你不能。

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,是的,不是的。您可以使用string.dump 获取操作码转储,但除了loadstring 将其返回之外,不支持以任何方式使用它,因此您需要自行解析它。
  • 其实还有@lhf的字节码检查库lbci(也可以通过LuaRocks获得)。
  • @Oleg 当我逐个字符打印出 string.dump 时,我没有得到说明,我错过了什么?
【解决方案2】:

我可能不会依赖它,但是 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()lua_getinfo()

【讨论】:

    猜你喜欢
    • 2017-05-08
    • 1970-01-01
    • 2016-07-17
    • 2013-08-13
    • 2010-11-03
    • 1970-01-01
    • 2012-10-14
    • 2012-01-08
    • 1970-01-01
    相关资源
    最近更新 更多