【问题标题】:Can I extract stack values from a parent function in Lua?我可以从 Lua 中的父函数中提取堆栈值吗?
【发布时间】:2012-09-01 03:01:33
【问题描述】:

我的游戏引擎将一个值作为函数的参数推送到 lua 堆栈,然后使用 lua_pcall 调用它。 lua 代码将运行并调用其他 lua 函数。最终,这个 lua 代码将调用一个 C 函数。此函数是否可以检索最初压入堆栈的值?

是这样的:

<engine function A>
  pushes parameter value X on to stack for lua
<lua func>
<lua func>
<lua func>
<engine function B>
  can I extract the values X that was pushed by function A here?

【问题讨论】:

  • 您可以使用调试界面来完成,但这将是一个可怕的组合。为什么不将值传递到堆栈中,或者以其他方式(全局、方法调用等)对其进行访问?
  • 现在我只是用一个全局变量将值保存在 C 中。在上图中,FUNCTION A 是游戏运行 LUA 代码的通用入口点,我不乐意添加该全局变量,因为只有当 lua 调用 FUNCTION B 时才需要该值
  • ...另一个限制是我想在有限的上下文中改变 FUNCTION B 的行为。在 Lua 中已经有 100 多次调用它,我不能通过所有它们推送一个额外的参数,所以 FUNCTION A 推送的参数可以对 FUNCTION B 可用。如果有一个简单的方法来清理的话访问我的调用堆栈中第一个 lua 函数的堆栈上的第一个变量

标签: lua stack


【解决方案1】:

是的,结合使用 getinfo、getlocal 和 getupvalue,您可以获得所有信息(您甚至可以使用 set* 函数更改这些值)。

这是来自MobDebug 的片段,它返回堆栈信息以及每个级别的局部变量和上值表。每个级别的变量将按照它们在代码中出现的顺序(从参数开始)进行索引。对于每个 get* 函数,您可以使用它们的 C 等效项(lua_getinfo、lua_getlocal 和 lua_getupvalue),但逻辑应该完全相同。

local function stack(start)
  local function vars(f)
    local func = debug.getinfo(f, "f").func
    local i = 1
    local locals = {}
    while true do
      local name, value = debug.getlocal(f, i)
      if not name then break end
      if string.sub(name, 1, 1) ~= '(' then locals[name] = {value, tostring(value)} end
      i = i + 1
    end
    i = 1
    local ups = {}
    while func and true do -- check for func as it may be nil for tail calls
      local name, value = debug.getupvalue(func, i)
      if not name then break end
      ups[name] = {value, tostring(value)}
      i = i + 1
    end
    return locals, ups
  end

  local stack = {}
  for i = (start or 0), 100 do
    local source = debug.getinfo(i, "Snl")
    if not source then break end
    table.insert(stack, {
      {source.name, source.source, source.linedefined,
       source.currentline, source.what, source.namewhat, source.short_src},
      vars(i+1)})
    if source.what == 'main' then break end
  end
  return stack
end

【讨论】:

  • 我需要从 C 中获取价值。让 C 代码运行更多 Lua 是我唯一的选择吗?这个 Lua 代码似乎需要做很多工作,到目前为止,我最好还是坚持将 FUNCTION A 的 C 端的全局变量中的值保存起来。我曾希望我可以使用Lua API,因为我知道参数位于哪个函数堆栈。
  • @Matt,我提供了一个完整的示例,以便您探索它的工作原理。如果您只需要访问堆栈中的函数中使用的局部变量,则需要进行一次调用:local name, value = debug.getlocal(f, i)。如果您知道该函数的堆栈层数,您可以设置f。如果您知道参数的顺序,您可以设置i 以获得您需要的确切参数。如果您没有其中的一些,则需要遍历函数/局部变量以通过查看它们的名称来找到所需的变量(这可能不起作用)。从 C 调用,你会使用 lua_getlocal。
猜你喜欢
  • 1970-01-01
  • 2017-08-16
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
  • 1970-01-01
  • 2013-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多