C++クラスの(純粋な)仮想関数をオーバーライドするクラスをpythonで作成しようとしています(を使用boost.python
)。問題は、C++ クラスが静的メンバー関数を介して作成されることです (すべてのコンストラクターはプライベートまたは削除されます)。Pythonが「知っている」クラス Base と BaseWrap クラスを正常に作成しました。また、Python でオーバーライドできる純粋な仮想関数を作成することもできました。ただし、私の問題は、 Base のメンバー関数が純粋仮想関数を呼び出すときです。これが発生すると、クラスは Python の実装を見つけることができず、プログラムがクラッシュします。
C++ コードは次のとおりです。
#include <iostream>
#include <boost/python.hpp>
#include <boost/static_assert.hpp>
#define CREATE(NAME) \
static std::shared_ptr<NAME> Create() { \
std::cout << "STATIC BASE CREATE" << std::endl; \
return std::make_shared<NAME>(); \
}
class Base {
protected:
Base() { std::cout << "BASE DEFAULT CONSTRUCTOR" << std::endl; }
private:
std::string CallSay() {
return Say();
}
virtual std::string Say() const = 0;
};
class BaseWrap : public Base, public boost::python::wrapper<Base> {
public:
BaseWrap() : Base() { std::cout << "BASEWRAP DEFAULT CONSTRUCTOR" << std::endl; }
virtual std::string Say() const override
{
std::cout << "C++ Say" << std::endl;
return this->get_override("say") ();
}
CREATE(BaseWrap)
};
BOOST_PYTHON_MODULE(Example)
{
namespace python = boost::python;
// Expose Base.
python::class_<BaseWrap, std::shared_ptr<BaseWrap>, boost::noncopyable>("Base", python::no_init)
.def("__init__", python::make_constructor(&BaseWrap::Create))
.def("Say", python::pure_virtual(&Base::Say))
.def("CallSay", &Base::CallSay);
}
問題をテストするための python コード:
import sys
import Example
class PythonDerived(Example.Base):
def __init__(self):
print "PYTHON DEFAULT CONSTRUCTOR"
Example.Base.__init__(self)
def Say(self):
return "Python Say"
d = PythonDerived()
print d
print
print d.Say()
print
print d.CallSay()
実行すると、次の出力が得られます。
PYTHON DEFAULT CONSTRUCTOR
STATIC BASE CREATE
BASE DEFAULT CONSTRUCTOR
BASEWRAP DEFAULT CONSTRUCTOR
<__main__.PythonDerived object at 0x1091caf70>
Python Say
C++ Say
Traceback (most recent call last):
File "test.py", line 20, in <module>
print d.CallSay()
TypeError: 'NoneType' object is not callable
Base::CallSay
メソッドが の実装を見つけているように見えBaseWrap::Say
ますが、Python の実装が見つかりません。誰もがなぜ、またはどのようにこれを機能させるのか知っていますか?
ありがとう!