【问题标题】:Custom PyObject by inheritance in C++在 C++ 中通过继承自定义 PyObject
【发布时间】:2016-03-19 07:03:58
【问题描述】:

长期 python 程序员,第一次 C++ 扩展作家。无论如何,为了好玩,我正在尝试在 C++ 中为 python 创建一个链表模块。这是我的代码

#include <python2.7/Python.h>
#include <iostream>

using namespace std;

template <typename T>
class LinkedList : public PyObject {
private:
  struct ListNode {
    ListNode(T value, ListNode* next)
      : value(value), next(next) {}
    T value;
    ListNode* next;
  };
  ListNode* head;

public:
  LinkedList(T value)
    : head(new ListNode(value, 0)) {
    cout << "class constructed" << endl;
    Py_INCREF(this);
  }
  void get_value() {
    cout << "test" << endl;
  }
  ~LinkedList() {
    delete head;
    Py_DECREF(this);
    cout << "class destructed" << endl;
  }
};

static PyObject* linkedlist_new(PyObject* self, PyObject* args) {
  LinkedList<char*> ll("hello");
  return Py_BuildValue("O", &ll);
}

static PyMethodDef LinkedListMethods[] = {
    {"new", linkedlist_new, METH_VARARGS,
     "Create a new linked list."},
    {NULL, NULL, 0, NULL}
};

extern "C" PyMODINIT_FUNC initLinkedList(void) {
  (void) Py_InitModule("LinkedList", LinkedListMethods);
}

我可以这样做吗?大多数文档都是针对 C 的,但是我可以从 PyObject 继承并像这样返回它吗?现在有效的是:

import LinkedList

print "start"
l = LinkedList.new()
print "done"

但只要我在 python 中调用l.get_value(),就会出现段错误。我知道我正在做的事情可能是错误的,所以有人会那么好心地指出我正确的方向吗?

为了澄清,我知道名为“ll”的LinkedList&lt;char*&gt;linkedlist_new 函数完成后被销毁,这是我遇到的问题的一部分。让我们假设我非常非常迷失......

【问题讨论】:

    标签: python c++ templates cpython pyobject


    【解决方案1】:

    首先:您可能需要手动设置对象标题 - 换句话说,更改

    template <typename T>
    class LinkedList : public PyObject { /* … */ }
    

    类似

    template <typename T>
    class LinkedList {
        public:
            PyObject_HEAD
            /// …
    }
    

    ...根据我自己的经验,后者可以正常工作,前提是 Python 对象的 API 的其余部分已正确填写。这是第二点:您没有定义 PyTypeObject,这比您在这里的内容更复杂(q.v. https://docs.python.org/2/c-api/typeobj.html)。

    具体来说,您需要一个 PyTypeObject 对应于您打算向用户公开的每个 PyObject 派生结构 - 因此,虽然模板化 PyObject 派生 LinkedList 类起初听起来不错,请记住PyTypeObject 结构(因为您的面向用户的模块表示将不可避免地必须具体定义其中的一个或多个)以及您的LinkList 最终专用于哪些typename 参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-21
      • 2020-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多