我试图用Python作为我的C++项目的脚本语言,所以我达到了Boost.Python使任务不那么乏味。我有一个C++类(Script系统),它负责保存和执行Python脚本。在
namespace py = boost::python;
class ScriptSystem : public System
{
public:
virtual void execute_scripts() override;
void addToPyGlobals(const OtherSystemsPtr&);
void addScript(IScript*);
private:
std::vector<IScript *> scripts;
py::dict python_globals;
};
Python脚本应该是被包装的C++接口的子类,名为IScript。在
^{pr2}$我设法向Python公开了ScriptSystem类和IScript接口,它几乎可以正常工作。我可以创建IScript的新实例并将它们传递给ScriptSystem而不会有任何麻烦。我可以创建重写tick(self)
的子类,只要它们不定义构造函数,我就可以开始了。在
namespace py = boost::python;
class ScriptWrapper : public Script::IScript, public py::wrapper<Script::IScript>
{
public:
void tick()const override
{
// Check for Python override
if(py::override f = this->get_override("tick")) {
std::cout << "Found Python override"
<< std::endl;
f();
return;
}
// If there is no override, call the default implementation
std::cout << "No Python override found, calling C++ implementation."
<< std::endl;
this->Script::IScript::tick();
return;
}
void default_tick() const {
return this->Script::IScript::tick();
}
};
BOOST_PYTHON_MODULE(_script)
{
py::class_<ScriptSystem, boost::noncopyable>("ScriptSystem")
.def("add_script", &ScriptSystem::addScript);
py::class_<ScriptWrapper, boost::noncopyable>("Script")
.def("tick", &Script::IScript::tick, &ScriptWrapper::default_tick);
py::implicitly_convertible<ScriptWrapper*, Script::IScript*>();
}
我可以向类添加数据属性,但是添加__init__(self)
会导致问题。例如,此代码段执行得很好:
(RemoteShell)
>>> from script import Script
>>> class One(Script):
... def tick(self):
... print "I'm a script!"
... print "My value is {}".format(One.value)
...
>>> One.value = 5
>>> one = One()
>>> script_system.add_script(one)
但是这个代码失败了:
(RemoteShell)
>>> from script import Script
>>> class Two(Script):
... def __init__(self):
... self.count = 0
... def tick(self):
... if self.count % 2 == 0:
... print "Tick"
... else:
... print "Tock"
... self.count += 1
...
>>> two = Two()
>>> script_system.add_script(two)
Traceback (most recent call last):
File "<console>", line 1, in <module>
ArgumentError: Python argument types in
ScriptSystem.add_script(ScriptSystem, Two)
did not match C++ signature:
add_script(ScriptSystem {lvalue}, Script::IScript*)
所以,我想我的问题是:这里发生了什么?!我不明白为什么向脚本的Python子类(IScript的Python包装器)添加构造函数会导致参数不匹配错误。在
当派生类提供^{} 方法时,它必须显式调用其基类
__init__
方法,以确保实例的基类部分正确初始化。在这种情况下,Two
实例的Script
部分没有正确初始化,导致Boost.Python是基于C++类型的故障调度。在要解决此问题,请考虑更改:
收件人:
^{pr2}$下面是一个完整的最小示例:
交互式使用:
相关问题 更多 >
编程相关推荐