问题:使用C-API构造从NumPy扩展的新类时,出现分段错误。
我一直在到处搜索,试图找到这个问题的答案,但是到处都有我发现与为NumPy编写扩展模块有关的东西,它们是提供使用NumPy数组的方法的模块,这不是我所需要的。寻找。
我想知道如何为NumPy编写一个扩展类,以便它在编译时在Code中静态定义,而不是在模块导入期间生成的,例如Cython / Python所做的事情。
他们在NumPy docs上写道,新结构应采用以下形式:
typedef _new_struct {
PyArrayObject base;
/* new things here */
} NewArrayObject;
(首先,对于这个_new_struct
实体应该是什么,我找不到任何东西。这很重要吗?)
然后,on a completely different tutorial,他们写道NumPy使用__new__而不是__init__,并且使用__finalize_array__代替__init__。
这里的问题是__new__应该负责创建新的NumPy数组并分配适当的内存,但是由于某些原因,由于我遇到了分段错误,因此似乎并非如此。
这是我的代码:
#define PY_SSIZE_T_CLEAN
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <Python.h>
#include "structmember.h"
#include "arrayobject.h"
#define PyString(s) PyUnicode_FromString(s)
typedef struct {
PyArrayObject base;
PyObject* name;
} NamedListObject;
static PyMemberDef NamedList_members[] = {
{"name", T_OBJECT_EX, offsetof(NamedListObject, name), 0, "Name of the list"},
{NULL},
};
static PyObject *
NamedList_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
NamedListObject *self;
self = (NamedListObject *) PyArray_Type.tp_new(type, args, kwds);
if (self == NULL)
return NULL;
if (self != NULL) {
self->name = PyString("");
if (self->name == NULL) {
Py_DECREF(self);
return NULL;
}
Py_INCREF(self);
}
return (PyObject *) self;
}
static PyTypeObject
NamedListType = {
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "test.NamedList",
.tp_doc = "A named list type",
.tp_basicsize = sizeof(NamedListObject),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
.tp_members = NamedList_members,
.tp_new = NamedList_new,
};
static PyModuleDef
testmodule = {
PyModuleDef_HEAD_INIT,
.m_name = "test",
.m_doc = "A subclassing test",
.m_size = -1,
};
PyMODINIT_FUNC
PyInit_test(void)
{
PyObject *module;
import_array();
NamedListType.tp_base = &PyArray_Type;
if (PyType_Ready(&NamedListType) < 0)
return NULL;
module = PyModule_Create(&testmodule);
if (module == NULL)
return NULL;
Py_INCREF(&NamedListType);
PyModule_AddObject(module, "NamedList", (PyObject *) &NamedListType);
return module;
}
我知道PyArray_New等方法,但是这些方法需要我准备参数。这个想法是让NumPy处理数组部分的创建,而不需要我打电话给__new __。