【问题标题】:Luabind: Can't return shared_ptrLuabind:无法返回 shared_ptr
【发布时间】:2013-02-08 21:12:58
【问题描述】:

我正在尝试从与 Luabind 绑定的方法返回 std::shared_ptr,但它似乎无法识别类型。

Luabind 代码:

module(lua)
[
    class_<Character, BaseEntity, std::shared_ptr<Character> > ("Character"),
        def("createCharacter", &Character::createCharacter)
];

创建字符代码:

std::shared_ptr<Character> Character::createCharacter(Game* gameInstance, const Character::CharacterSetup& characterSetup, string sprite, b2World* world)
{
    return std::shared_ptr<Character>(new Character(gameInstance, characterSetup, sprite, world));
}

如果我在 Lua 脚本中调用此方法,则不会返回任何内容,并且执行会停在那里。但是,如果我将方法更改为返回 Character*,它会按预期工作。一些谷歌搜索告诉我返回 shared_ptr 应该不是问题。

我做错了什么?

另外,我有这段代码,所以 Luabind 可以理解 std::shared_ptr:

namespace luabind
{
    template <typename T>
    T* get_pointer(std::shared_ptr<T> const& p)
    {
        return p.get();
    }
}

【问题讨论】:

  • 你试过boost::shared_ptr&lt;T&gt;吗?
  • 我对luabind不太熟悉,但是如果它不存储共享指针而只是使用get_pointer()来获取真正的指针,它会丢弃最后一个引用(从而删除对象) 而它保持(现在悬空的)指针。首先,确保您的课程正确地不可复制。其次,给构造函数和析构函数添加断点。

标签: c++ lua shared-ptr luabind


【解决方案1】:

我必须解决同样的问题。

这有点复杂。基本上你需要用原型定义一个函数

template <typename T>
T* get_pointer(std::shared_ptr<T> const&);

此函数还必须与std::shared_ptr 位于相同的命名空间中,即std::。请注意,全局命名空间或luabind 命名空间中的函数,如您的那样,将不起作用,因为 luabind 使用 special tricks 来确保在以下情况下仅使用 ADL检查某个类型是否是智能指针。避免这种情况的唯一方法是在 luabind::detail::has_get_pointer_ 命名空间中定义您的函数,而不仅仅是 luabind

但是单独在这个命名空间中定义你的函数也不起作用(至少对于 Boost std 中定义函数,但这是 Boost std::shared_ptr(和 std::unique_ptr)定义了自己的 boost::get_pointer() 重载。对于这个版本,足以让 Boost 的 get_pointer()luabind::detail::has_get_pointer_ 命名空间中可见,因为 luabind 是 using 这个函数在它使用智能指针的任何地方(参见 luabind/get_pointer.hpp 标头)。在 std 中定义函数甚至不会起作用,因为 luabind 会引发模棱两可的调用。

因此,如果您想要 std::shared_ptrget_pointer() 重载,它适用于 Boost = 1.53 以及 MSVC 10(可能还有 9)(这些在 std::tr1 中定义 shared_ptr 而不是 @987654342 @),我可以为您提供我的(历史悠久的 ;-) )标题:

#ifndef SHAREDPTR_CONVERTER_HPP_INCLUDED
#define SHAREDPTR_CONVERTER_HPP_INCLUDED SHAREDPTR_CONVERTER_HPP_INCLUDED

#include <boost/version.hpp>

#if BOOST_VERSION >= 105300

#include <boost/get_pointer.hpp>


namespace luabind { namespace detail { namespace has_get_pointer_ {
    template<class T>
    T * get_pointer(std::shared_ptr<T> const& p) { return p.get(); }
}}}

#else // if BOOST_VERSION < 105300

#include <memory>

// Not standard conforming: add function to ::std(::tr1)
namespace std {

#if defined(_MSC_VER) && _MSC_VER < 1700
namespace tr1 {
#endif

    template<class T>
    T * get_pointer(shared_ptr<T> const& p) { return p.get(); }

#if defined(_MSC_VER) && _MSC_VER < 1700
} // namespace tr1
#endif

} // namespace std

#endif // if BOOST_VERSION < 105300

#endif

【讨论】:

  • 太棒了太棒了。谢谢谢谢谢谢。
猜你喜欢
  • 1970-01-01
  • 2012-05-13
  • 1970-01-01
  • 2012-07-21
  • 2019-01-27
  • 1970-01-01
  • 1970-01-01
  • 2011-05-24
  • 1970-01-01
相关资源
最近更新 更多