gpt4 book ai didi

c++ - luabind : Accessing an invalidated c++ object from lua results in access violation

转载 作者:行者123 更新时间:2023-11-30 04:21:28 25 4
gpt4 key购买 nike

luabind 是否可能检查对导出类(对象)的成员函数调用是否针对有效对象?

假设我有一个名为 Actor 的类,使用 luabind 暴露给 lua。我使用 actor 对象作为参数从 C++ 调用 lua 函数。现在,在函数完成之前,脚本编写会将 actor 对象放入全局 lua 引用中,以便稍后访问。

稍后,actor 对象从 C++ 站点中删除,另一个函数被调用,它试图访问无效的 actor 对象(来自它的任何方法)——显然,由于它已被删除,它导致崩溃(访问违反)

示例:

local myObjRef = nil

function doSomethingWithActor(actor)
-- save, still valid object
actor:Say("hello")
myObjRef = actor
end

function calledAfterActorWasDeleted()
--- will crash if the c++ object has been deleted meanwhile, works fine if it still exists
myObjRef:Say("Crash...")
end

NIL 检查在这里没有帮助,这可以在 luabinds 站点上检查吗?这些函数使用 lua_pcall(....) 执行,堆栈跟踪显示 luabinds call.hpp results = maybe_yield(L, lua_gettop(L) - arguments, (Policies*)0);

如果不是,是否有另一种解决方案如何确保编写脚本的人不会造成这些问题?

最佳答案

Now before the function finishes, a script write would put the actor object in a global lua reference to be accessed later.

这就是您的问题所在。如果你想让 Lua 代码拥有这个对象(也就是说,保留这个对象的存在),那么你需要使用 Luabind 机制来告诉 Luabind 你想要那样做。否则,如果您将指针传递给某个 Lua 函数,Luabind 将假定该函数不会尝试获取它的所有权。

如果你想在 Lua 和 Luabind 之间共享所有权,那么你应该将你的对象包装在 boost::shared_ptr 中,并使用 Luabind 的智能指针机制来做这个。

您还可以更好地隔离脚本。如果您有一些对特定 actor 进行操作的脚本,那么该脚本及其包含的任何函数都应该与对象一起销毁(即:丢失对它的所有引用)。这需要在 C++ 端有适当的编码规则。它还将要求您使用 Lua 环境来正确封装脚本的每个实例,以便它们无法通过全局变量偷偷溜走。最后,您需要让 C++ 保持对何时调用脚本以及何时不调用脚本的完全控制。

否则,您的脚本编写者将不得不了解并注意所有权。他们不能像对待任何旧的 Lua 值一样对待 C++ 参数。


如果严格的编程实践对您来说不可能或不切实际,那么您只需不向 Lua 传递实际的 C++ 对象即可。相反,您需要向 Lua 传递一些代理对象,这是对原始对象的引用。 boost::weak_ptr 是此类对象的一个​​很好的示例(尽管您不会将其完全传递给 Lua)。代理会将调用转发给实际对象。如果对象已被删除,代理将检测到这一点并失败或什么都不做或做任何事情。

关于c++ - luabind : Accessing an invalidated c++ object from lua results in access violation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14531216/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com