Mik*_*ike 5 python numpy python-c-api python-c-extension
使用C API,我想创建一个包含类型对象的numpy数组Quaternion,这是我用C++编写的类.我已经有了这些数组(实际上是a std::vector),我想制作一个副本 - 或者如果可能的话使用相同的内存.
由于这不是基本类型,我需要使用Py_Object类型,不能使用PyArray_SimpleNew或类似的任何容易.
我猜我可能想要使用PyArray_NewFromDescr甚至PyArray_SimpleNewFromDescr,但我完全彻底迷失了如何创建PyArray_Descr我需要描述我的Quaternion类的对象.
谁能给我一些关于如何制作那个descr对象的指针?或者让我更好地了解如何构建我的numpy数组?
这基本上是这个问题的更一般版本,没有分心.
使用dastrobu的提示和我的SWIG包装器,我找到了一种方法.我知道不是每个人都在使用SWIG,但对于那些人,我对其他问题的回答显示了我是如何解决的.
由于Quaternion不是直接数字类型,因此您的数组必须具有numpy.objectas dtype。因此,您可以用来PyArray_SimpleNew(..., NPY_OBJECT)创建一个数组并填充数据。问题是你的Quaternion类不是 python 类型。因此,用对类型对象的引用填充数组Quaternion是行不通的。(在这种情况下,如果您从 python 中填充四元数的数组中提取一个元素,您期望会发生什么?)相反,您需要使用Quaternion类似PyQuaternion. 包装器负责引用计数和内存管理。它看起来像:
typedef struct {
PyObject_HEAD
Quaternion *q;
}PyQuaternion;
static PyTypeObject PyQuaternion_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"Quaternion", /*tp_name*/
sizeof(PyQuaternion), /*tp_basicsize*/
/* ... */
};
static PyObject *
PyQuaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds){
/* ... */
};
static int
PyQuaternion_init(PyQuaternion *self, PyObject *args, PyObject *kwds){
/* ... */
};
static void PyQuaternion_dealloc(PyQuaternion *self){
/* ... */
};
Run Code Online (Sandbox Code Playgroud)
此外,您可以定义自己的 C-API,以便PyQuaternionType您可以PyQuaternions从Quaternions
static PyObject *
PyQuaternion_New(Quaternion *q){
PyQuaternion *self;
self = (PyQuaternion *)PyQuaternion_Type.tp_new(type, NULL, NULL);
self->q = q;
return (PyObject *)self;
}
Run Code Online (Sandbox Code Playgroud)
请注意,这self->q将由PyQuaternion_dealloc函数处理,因此请考虑内存管理。最简单的是将所有权传递给包装器并让PyQuaternion_deallocdeallocate self->q。
该PyQuaternion_New函数允许您包装Quaternion对象并将它们填充到任何 python 容器中,例如列表、元组,当然还有带有dtype = numpy.object.