我正在尝试为运行 lua 脚本的进程编写一个调试器,记录的方法(用 C 语言)是使用
lua_sethook
:
int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
lua_Hook
定义为:
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
该钩子仅获取一个
lua_State
指针,这很棒,但是如何将指向我的调试器类的指针与它关联起来,以便我可以从那里返回到我的调试器类?
我想避免在这种情况下使用全局变量,因为我有多个
lua_State
实例。我想我可以使用指向调试器实例的 lua_State *
指针映射,但这似乎效率不高。将其作为全局变量存储在 lua_State *
中似乎没有意义,因为为了能够检索它,我必须将至少一个值推送到 lua 堆栈上,这似乎很难/不可能做到lua 堆栈溢出的情况。
我错过了什么吗?我将如何实现这个目标?我知道,我可以在 lua 代码中完成此操作,但我想了解如何从 C 端执行此操作。
我注意到
lua_State
中有一个额外的空格,你可以用lua_getextraspace
得到它。根据手册,Lua 本身并没有触及它。默认情况下,其大小为 sizeof(void*)
。所以也许你可以在lua_newstate
之后分配一个自定义结构,在调试钩子中使用它,并在lua_close
之前自行释放它。
最终,您不能直接将值与钩子函数关联。
但是您可以通过多种方式间接做到这一点。最安全的可能是将值放在 Lua 注册表 中的已知位置。您也可以将其设为全局。但无论你怎么做,它都必须是可以通过
lua_State
对象访问的东西。
使用已注册 Lua 实例外部的数据是危险的。也就是说,您可能有一个关联容器,它将
lua_State
指针映射到注册的实例数据。但是,如果您尝试这样做,如果在 Lua 协程执行期间调用钩子函数,则可能会失败,因为它们具有与主线程分开的 lua_State
对象。