5

私たちのグループは、C++を使用して数値フレームワークを開発しています。ここで、フレームワークの基本部分をラップして、Pythonで使用できるようにします。私たちが選んだ武器はBoost.Pythonです。これは、他の目的でもすでにBoostになっているためです。ポリモーフィズムをサポートするためにsmart_ptrsのみを使用します。次のスニペットは、戦略パターンを適用する方法の簡単な例です。

#include <boost/shared_ptr.hpp>
struct AbsStrategy
{
  virtual std::string talk( ) = 0;
};

typedef boost::shared_ptr<AbsStrategy> StrategyPtr;

struct Foo : AbsStrategy
{
  std::string talk( )
  {
    return "I am a Foo!";
  }
};

struct Bar : AbsStrategy
{
  std::string talk( )
  {
    return "I am a Bar!";
  }
};

struct Client
{
  Client( StrategyPtr strategy ) :
          myStrategy( strategy )
  {
  }

  bool checkStrategy( StrategyPtr strategy )
  {
    return ( strategy == myStrategy );
  }

  StrategyPtr myStrategy;
};

Boost.Pythonを使用して全体をラップすると

#include <boost/python.hpp>
using namespace boost::python;

BOOST_PYTHON_MODULE( BoostPython )
{
  class_<Foo>( "Foo" )
      .def( "talk", &Foo::talk );

  class_<Bar>( "Bar" )
      .def( "talk", &Bar::talk );

  class_<Client>( "Client", init<StrategyPtr>( ) )
      .def( "checkStrategy", &Client::checkStrategy );
}

コンパイル中に次の警告が表示されます

C:/boost/include/boost-1_51/boost/python/object/instance.hpp:14:36: warning: type attributes ignored after type is already defined [-Wattributes]

Pythonでラッパーを使用しようとすると、次のエラーが発生します

>>> from BoostPython import *
>>> foo = Foo()
>>> bar = Bar()
>>> client = Client(foo)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
    Tree.__init__(Tree, Foo)
did not match C++ signature:
    __init__(_object*, boost::shared_ptr<AbsStrategy>)
>>> client = Client(bar)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
    Tree.__init__(Tree, Bar)
did not match C++ signature:
    __init__(_object*, boost::shared_ptr<AbsStrategy>)

フレームワークを変更せずにすべてを機能させるために欠けているものは何ですか?もちろん、ラッパーは自由に適合させることができます。

4

1 に答える 1

4

わかりました、解決策を見つけました。implicitly_convertible以下に示すように、モジュール宣言で使用する必要があります。

#include <boost/python.hpp>
using namespace boost::python;

BOOST_PYTHON_MODULE( BoostPython )
{
  class_<Foo>( "Foo" )
      .def( "talk", &Foo::talk );

  class_<Bar>( "Bar" )
      .def( "talk", &Bar::talk );

  class_<Client>( "Client", init<StrategyPtr>( ) )
      .def( "checkStrategy", &Client::checkStrategy );

  implicitly_convertible<boost::shared_ptr<Foo> , StrategyPtr>();
  implicitly_convertible<boost::shared_ptr<Bar> , StrategyPtr>();
}
于 2013-01-24T13:23:52.157 に答える