python - 在 C++ 中通过继承自定义 PyObject

标签 python c++ templates cpython pyobject

长期的 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"

但是一旦我调用l.get_value()在 python 中,我遇到了段错误。我知道我在做的事情可能是错误的,所以有人能给我指出正确的方向吗?

为了澄清,我知道 LinkedList<char*>名为“ll”的在linkedlist_new之后被销毁功能已完成,这是我遇到的问题的一部分。让我们假设我非常非常迷路......

最佳答案

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

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 参数专门化。

关于python - 在 C++ 中通过继承自定义 PyObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34256202/

相关文章:

c++ - 如何将 QGraphicsScene 动画渲染到电影文件中?

c++ - 如何防止 Visual Studio 发出有关缺少调试信息的警告?

列表字典中的 Python 最小值

python - numpy dtype 中的 > < 符号是什么意思?

c++ - 整数除法与浮点除法 -> 谁负责提供结果?

c++ - 标准化直方图?

c++ - 所有子类的模板特化

C++ 在模板类的情况下重载 operator+

c++ - 使用类模板参数比使用实例变量有什么好处?

python - 添加此语法的是哪个版本的 python