Python — Пользовательский PyObject по наследству в переполнении стека

Долгосрочный программист на Python, первый раз писатель расширений C ++. В любом случае, ради интереса, я пытаюсь создать модуль связанного списка для Python на C ++. Вот мой код

#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() в питоне я получаю сегфо Я знаю, что то, что я делаю, вероятно, неправильно, поэтому кто-нибудь был бы так добр, чтобы указать мне правильное направление?

И для уточнения, я знаю LinkedList<char*> по имени «ЛЛ» уничтожается после linkedlist_new функция выполнена, что является частью проблемы, которую я имею. Давайте просто предположим, что я очень, очень потерян …

4

Решение

Прежде всего: вам может понадобиться вручную настроить заголовок объекта — другими словами, изменить

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

что-то вроде

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

… По моему собственному опыту последний работает, при условии, что остальная часть API объекта Python заполнена правильно. Что является вторым моментом: вы не определяете PyTypeObject, который немного более вовлечен (кв. https://docs.python.org/2/c-api/typeobj.html) чем то, что у вас здесь.

В частности, вам понадобится PyTypeObject что соответствует каждому PyObjectструктура, которую вы намереваетесь показать пользователю PyObject-derived LinkedList Сначала класс может звучать великолепно, сохраняйте PyTypeObject структуры (поскольку представление вашего пользовательского модуля неизбежно должно будет конкретно определять один или несколько из них), а также какие typename параметры, на которых ваш LinkList заканчивается специализированным.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]