【问题标题】:Checking for protected mode in Lua C检查 Lua C 中的保护模式
【发布时间】:2013-01-28 23:29:43
【问题描述】:

在 Lua C 处理程序中,我在抛出错误之前在注册表中设置了一个标志。如果使用 pcall 从 Lua 调用处理程序,我想确保设置(或清除)此标志。以下是更多详细信息:

我有一个基本的 Lua 函数 handle 使用 lua_pcall 从 C 调用:

function handle()
  c_handle()
end

C 中的句柄具有下面的基本结构,我们希望在抛出错误之前设置一个标志以将错误与其他错误区分开来。

int c_handle(lua_State *L)
{
  if (condition) {
    set a flag in registry
    throw error with lua_error
}

如果 Lua 使用 pcall 调用处理程序,我想要么不设置注册表标志,要么清除它:

function handle()
  pcall(c_handle)
end

【问题讨论】:

  • 你能用你自己的版本替换pcall吗?

标签: lua


【解决方案1】:

您可以对脚本进行沙箱处理并将pcall 替换为您自己的版本,该版本会回调c_handle(),如下所示:

local newenv = {
    pcall = function(f, arg1, arg2, ...)
        if pcall(f, arg1, arg2, ...) then
            c_handle(true) -- no error, pass true to c_handle
        else
            c_handle(false) -- error, pass false to c_handle
        end if
    end
}
setmetatable(newenv, {__index = _G})
setfenv(1, newenv)

所以现在当您进行受保护的呼叫时,它将通过c_handle

编辑

不太确定将参数传递给 C 函数的语法,但我想这将是它的基本要点。

【讨论】:

  • 如果 pcall 捕获到错误,则需要重置 c_handle 中设置的标志。所以,我认为在这种情况下,pcall 包装器需要是 C。
  • @NoahWatkins 一点也不,pcall 出错时返回 false,所以您所要做的就是通过 c_handle 发送一个标志,尽管现在对 c_handle 的调用将在 pcall 之后进行。不过很容易更改,调用c_handle,将pcall 返回值存储在一个变量中,然后调用你的C 函数来获取标志。不确定将参数发送到 C 函数的确切语法,但我希望它类似于常规函数调用。我已经对我的帖子进行了一些编辑以反映这一点。
  • 啊,我的评论中隐含的是我不想通过 c_handler 接口公开这个功能。有没有办法让带有标志的 c_handler 版本只能从pcall 包装器?
  • @NoahWatkins 没有在 Lua 中编写处理程序或通过 Lua 设置标志,我认为你不能。您可以使处理程序需要某种键,但据我所知,这是唯一的解决方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-09
  • 2016-11-02
  • 2015-07-16
  • 2012-11-08
  • 2013-12-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多