首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Luabind中的断言失败

Luabind中的断言失败
EN

Stack Overflow用户
提问于 2011-06-04 20:48:57
回答 2查看 635关注 0票数 3

我目前在使用Luabind将Lua脚本AI与C++游戏接口时遇到了问题。

我在循环内调用更新函数(每帧调用一次),该函数从在Luabind中注册的C++函数检索信息。

我的问题如下:在一个可变的、不可预测的时间之后,在Luabind中有一个断言失败,这会导致中止。在Lua内部下降时,错误总是出现在/usr/include/luabind/wrapper_base.hpp:124中。

你知道什么能做到这一点吗?在我的测试中,C++和LUA中调用的函数总是相同的。

有关问题的更多详细信息:

围绕在wrapper_base.hpp中失败的断言的内容

代码语言:javascript
复制
typedef typename boost::mpl::if_<boost::is_void<R>, luabind::detail::proxy_member_void_caller<boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> >
, luabind::detail::proxy_member_caller<R, boost::tuples::tuple<BOOST_PP_ENUM(BOOST_PP_ITERATION(), LUABIND_TUPLE_PARAMS, _)> > >::type proxy_type;

// Comments removed

lua_State* L = m_self.state();
m_self.get(L);
assert(!lua_isnil(L, -1));
detail::do_call_member_selection(L, name);

if (lua_isnil(L, -1))
  {
    lua_pop(L, 1);
    throw std::runtime_error("Attempt to call nonexistent function");
  }

// push the self reference as the first parameter
m_self.get(L);

// now the function and self objects
// are on the stack. These will both
// be popped by pcall
return proxy_type(L, args);

确切的错误

代码语言:javascript
复制
bomberman: /usr/include/luabind/wrapper_base.hpp:124: typename boost::mpl::if_<boost::is_void<T>, luabind::detail::proxy_member_void_caller<boost::tuples::tuple<boost::tuples::null_type,       boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> >, luabind::detail::proxy_member_caller<R, boost::tuples::tuple<boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type,
boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >::type luabind::wrap_base::call(const char*, luabind::detail::type_<Derived>*) const [with R = void]:
Assertion `!(lua_type(L, (-1)) == 0)' failed.
Aborted (core dumped)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-02-20 06:36:28

几天前我遇到了这个问题。在我的特殊情况下,隐式创建的Lua表包含了在Lua中被覆盖的所有方法,每个对象都被垃圾收集,而底层的C++对象没有。正因为如此,如果您尝试从C++对象调用Lua成员函数,它将失败。

在我的例子中,解决方案是只要C++实例是活动的,就保持对lua表的引用是活动的。这很简单,只需向C++类添加一个luabind::object字段,然后在实例化该类时设置它,当调用C++类的析构函数时,它将被销毁,因此在大多数情况下,您不必担心内存泄漏。我的代码现在看起来像这样:

代码语言:javascript
复制
class LuaC : public BaseC, public luabind::wrap_base {
    private:
        luabind::object _self; //retain a reference to the Lua part of this object so it doesn't get gc'd
    public:
        void setSelf(luabind::object nSelf) { _self=nSelf; }
};
//expose LuaC including the method setSelf
// ...

(BaseC是您包装的C++类)

然后在Lua中,每当您实例化LuaC的实例时,都会调用setSelf并将self作为附加参数传递

代码语言:javascript
复制
c = LuaC()
c:setSelf(self)

如果没有一种方法可以简化这一切,并将其全部放在LuaC构造函数中,这样它就不容易出错(即,这样你就不必担心每次都调用setSelf ),我会感到惊讶。但是LuaBind的文档相当肤浅,所以我找不到任何方法来做到这一点。

此外,我认为这个问题发生的唯一方式是如果你告诉Luabind只使用像shared_ptr这样的引用,因为这样的话,Lua部分的get垃圾回收,连同shared_ptr,但不一定是指针引用的C++实例。如果Lua在管理整个实例,那么我不明白如何在C++实例继续存在的同时删除Lua表。

票数 3
EN

Stack Overflow用户

发布于 2013-08-17 23:04:00

看起来你正遭受着对象所有权分离的困扰。当C++类的包装器没有正确包装虚拟方法时,通常会发生这种情况。

我以前遇到过这个问题,但在我小心地实现了包装器之后,这个问题就消失了。在我的库中,我不需要这里提到的解决方法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6236827

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档