使用 Boost Python 从 c++ 类创建派生的 Python 类

Posted

技术标签:

【中文标题】使用 Boost Python 从 c++ 类创建派生的 Python 类【英文标题】:Create derived python class from a c++ class using Boost Python 【发布时间】:2015-12-21 20:59:39 【问题描述】:

我有一个共享库,我用 boost python 创建了一堆类,我希望能够从 python 中的这些类继承。继承位似乎工作正常,但我无法调用超类中的方法。

c++类定义:

class Game 
    vector<pair<object, Listener*> > _listeners;

public:
    Game();

    virtual void assignListener(object listener);
    vector<pair<object, Listener*> >& listeners();
;

这个类的 boost python 包装器看起来像这样:

BOOST_PYTHON_MODULE(libgla) 
    using namespace boost::python;

    ...

    class_<Game>("Game", init<>())
            .def("assign_listener", &Game::assignListener);

    ...
;

我的 python 测试代码如下所示:

from libgla import Engine, Game, Window, ErrorListener, KeyListener


class CustomGame(Game):
    def __init__(self):
        self.assign_listener(KeyListener())

engine = Engine(ErrorListener())
engine.set_game(CustomGame())
engine.set_window(Window(1280, 1024, "test"))
engine.start()

此代码在 assign_listener 函数上终止,并出现以下错误:

Traceback (most recent call last):
  File "app.py", line 9, in <module>
    engine.set_game(CustomGame())
  File "app.py", line 6, in __init__
    self.assign_listener(KeyListener())
Boost.Python.ArgumentError: Python argument types in
    Game.assign_listener(CustomGame, KeyListener)
did not match C++ signature:
    assign_listener(Game lvalue, boost::python::api::object)

是我做错了什么还是这是 boost python 的限制?

注意:以下 python 代码可以正常工作

from libgla import Engine, Game, Window, ErrorListener, KeyListener

engine = Engine(ErrorListener())
game = Game()
game.assign_listener(KeyListener())
engine.set_game(game)
engine.set_window(Window(1280, 1024, "test"))
engine.start()

编辑 1

我认为 instance_holder 描述的 here 是答案,但我不知道如何实现它,文档并没有给出明确的例子。

【问题讨论】:

是 boost::python::api::object 的 KeyListener 子项? mhh 不,这会导致问题吗?你的意思是我应该继承 boost::python::api::object 吗?因为我的印象是我需要做的就是实现 class_ 并且 boost python 应该知道它。 我在很远的地方做了这个(可能不记得了),尝试这样做或方法“assignListener”必须接收 KeyListener,而不是对象。它无法将您的调用应用于您的方法 实际上这不是问题,因为它可以正常工作:game = Game() game.assign_listener(KeyListener()) 我对这个问题的想法是 c++ Boost::Python Game 对象不将 CustomGame 识别为派生类,因此失败。只是文档有点稀疏,找不到解决办法。 【参考方案1】:

试试这个:

class CustomGame(Game):
    def __init__(self):
        Game.__init__(self)
        self.assign_listener(KeyListener())

您错过了超类初始化。没有它,使用你的基类就不是真的有效。

【讨论】:

能否请您 edit 解释一下为什么这段代码回答了这个问题? 感谢它的工作,我不敢相信我什至没有考虑到这一点。我很久没用python编程了,这正常吗,即使它只是一个默认的超级构造函数,你也总是需要运行它吗?

以上是关于使用 Boost Python 从 c++ 类创建派生的 Python 类的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 PyObjects 声明 Boost.Python C++ 类

使用 boost::python 从 c++ 函数访问大表

如何使用 Boost Python 从 C++ bool 转换为 Python boolean?

Boost.Python 如何拥有 C++ 类?

从boost python模块中的pyside导入类?

boost-python:如何提供自定义构造函数包装函数?