代码之家  ›  专栏  ›  技术社区  ›  Dewfy

Python C++扩展中的继承

  •  3
  • Dewfy  · 技术社区  · 15 年前

    我有C++库,需要与Python插入的模块通信。通信假定由Python实现一些回调C++接口。

    我已经阅读过有关编写扩展的内容,但不知道如何开发继承。

    所以关于: C++:

    class Broadcast
    {
       void set(Listener *){...
    }
    
    class Listener
    {
        void notify(Broadcast* owner) = 0;
    }
    

    我需要类似于python的东西:

    class ListenerImpl(Listener):
        ...
        def notify(self, owner):
            ...
    

    注意,我不想使用Boost。

    2 回复  |  直到 8 年前
        1
  •  5
  •   Thomas Wouters    15 年前

    在C中编写可继承的python类型在 PEP 253 . 这与编写一个普通的内置类型没有什么不同,如中所述。 the Extending/Embedding guide 但是您必须通过python api执行某些操作,比如属性访问,而不是直接访问任何东西。

    将Python子类暴露回C++代码有点乏味。Python类不是C++子类,因此需要一个C++继承器类(继承了 Listener )包含一个 PyObject* 对于python子类实例,它具有 notify 方法将参数转换为python对象,调用 通知 方法 复制对象* (例如, PyObject_CallMethod ),将结果翻译回C++类型,然后返回。

        2
  •  5
  •   codie    8 年前

    因为我必须执行 单一继承 作为我的一个项目中python c-api的一部分,我构建了一个 short example here . 我在代码中标记了重要的语句。

    诀窍是继承子类结构顶部的基结构(不包括 PyObject_HEAD 声明)。

    /* OBJECT */
    typedef struct {
          MyPy_BaseClass super; // <----- PUTTING THIS FIRST INHERITS THE BASE PYTHON CLASS!!!
          // Own variables:
          // e.g int x = 0;
    } MyPy_InheritanceClass;
    

    也不要忘记将基类型赋予子类类型。它有一面旗帜(见 /* tp_base */ )

      static PyTypeObject MyPy_InheritanceClass_Type = {
        PyVarObject_HEAD_INIT(NULL, 0)
        "MyPy_InheritanceClass",          /* tp_name */
        sizeof(MyPy_InheritanceClass),    /* tp_basicsize */
        0,                         /* tp_itemsize */
        (destructor)MyPy_InheritanceClass_dealloc, /* tp_dealloc */
        0,                         /* tp_print */
        0,                         /* tp_getattr */
        0,                         /* tp_setattr */
        0,                         /* tp_reserved */
        0,                         /* tp_repr */
        0,                         /* tp_as_number */
        0,                         /* tp_as_sequence */
        0,                         /* tp_as_mapping */
        0,                         /* tp_hash  */
        0,                         /* tp_call */
        0,                         /* tp_str */
        0,                         /* tp_getattro */
        0,                         /* tp_setattro */
        0,                         /* tp_as_buffer */
        Py_TPFLAGS_DEFAULT |
        Py_TPFLAGS_BASETYPE,       /* tp_flags */ 
        "MyPy_InheritanceClass",   /* tp_doc */
        0,                         /* tp_traverse */
        0,                         /* tp_clear */
        0,                         /* tp_richcompare */
        0,                         /* tp_weaklistoffset */
        0,                         /* tp_iter */
        0,                         /* tp_iternext */
        MyPy_InheritanceClass_methods,    /* tp_methods */
        0,                         /* tp_members */
        0,                         /* tp_getset */
        &MyPy_BaseClass_Type,      /* tp_base */ // <------ GIVE THE BASE_CLASS TYPE
        0,                         /* tp_dict */
        0,                         /* tp_descr_get */
        0,                         /* tp_descr_set */
        0,                         /* tp_dictoffset */
        (initproc) MyPy_InheritanceClass_init, /* tp_init */
        0,                         /* tp_alloc */
        MyPy_InheritanceClass_new, /* tp_new */
    };