4

Luabind でバインドされたメソッドから std::shared_ptr を返そうとしていますが、型を認識していないようです。

ルバインドコード:

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();
    }
}
4

1 に答える 1

5

私はまったく同じ問題を解決しなければなりませんでした。

少し複雑です。基本的に、プロトタイプで関数を定義する必要があります

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

さらに、この関数は と同じ名前空間に存在する必要があるstd::shared_ptrため、std::. luabind は、特定の型がスマート ポインターであるかどうかを確認するときに ADL のみが使用されるようにする特別なトリックを使用するため、グローバル名前空間またはluabind名前空間内の関数は、あなたのものとしては機能しないことに注意してください。これを回避する唯一の方法は、関数を名前空間で定義することです。luabind::detail::has_get_pointer_luabind

ただし、この名前空間だけで関数を定義しても機能しません (少なくとも Boost <1.53 の場合)。名前空間で関数を定義することはstd、C++ 標準では技術的に許可されていませんが、Boost <1.53 で可能な唯一の方法です。ただし、1.53 以降、Boost は(および) の独自のboost::get_pointer()オーバーロードを定義します。このバージョンでは、名前空間で Boost を可視化するだけで十分です。これは、luabind がスマート ポインターを使用する任意の場所にあるためです (ヘッダーを参照)。luabind があいまいな呼び出しを引き起こすため、関数を定義しても機能しません。std::shared_ptrstd::unique_ptrget_pointer()luabind::detail::has_get_pointer_usingluabind/get_pointer.hppstd

したがって、Boost <1.53 および >= 1.53 と MSVC 10 (およびおそらく 9) (これらは ではなく で定義) で機能するオーバーget_pointer()ロードが必要な場合は、(歴史的に成長した ;-) ) ヘッダーを提供できます。std::shared_ptrshared_ptrstd::tr1std

#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
于 2013-03-04T17:50:04.497 に答える