如何将lua_sethook上下文与lua_sethook相关联?

3

我正在尝试为运行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_State,最多只能有一个调试器类吗?调试器类是否可以在多个 lua_State 之间共享,还是每个 lua_State 都有自己独立的唯一调试器类? - greatwolf
在我的情况下,这是一种1:1的关系。调试器类具有指向一个lua_State的指针,我需要有效地能够在lua_Hook函数中从lua_State获取到调试器类。 - Tom
2
把它存储在Lua注册表里怎么样?您仍然需要在您的 hook 函数中将其推入堆栈,但我不确定为什么您要担心它会溢出。您不能只做一个 lua_checkstack,如果失败了就在您的C代码中处理它吗? - greatwolf
我想我可以这样做。目前,我正在维护一个状态指针到调试器的映射表。虽然不是理想的解决方案,但由于所有脚本都在同一线程中运行,所以我可以不使用任何锁来完成。我希望有更轻量级的解决方案。 - Tom
2个回答

0

最终,您无法直接将值与钩子函数关联。

但是,您可以通过各种方式间接地实现。最安全的方法可能是将该值放在Lua注册表中已知的位置。您也可以将其设置为全局变量。但是,无论如何,它都需要是可以通过lua_State对象访问的内容。

使用外部于已注册的Lua实例的数据是危险的。也就是说,您可能会有一个关联容器,将lua_State指针映射到已注册实例数据。但是,如果您尝试这样做,则在Lua协程执行期间调用钩子函数时可能会失败,因为它们具有与主线程不同的lua_State对象。


0
我注意到 lua_State 里有一个额外的空间,你可以用 lua_getextraspace 来获取它。根据手册,Lua 自己不会对此进行任何操作。默认情况下,它的大小是 sizeof(void*)。因此,也许你可以在 lua_newstate 之后分配一个自定义结构体,在调试钩子中使用它,并在 lua_close 之前自行释放它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接