由于Quaternion 不是直接数字类型,因此您的数组必须具有numpy.object 和dtype。因此,您可以使用PyArray_SimpleNew(..., NPY_OBJECT) 创建一个数组并填写数据。
问题是您的 Quaternion 类不是 python 类型。所以用Quaternion 类型的对象的引用填充数组是行不通的。 (在这种情况下,如果您从填充了 python 的四元数的数组中提取一个元素,您希望发生什么?)
相反,您需要用PyQuaternion 之类的东西包装Quaternion 类。包装器负责引用计数和内存管理。它看起来像:
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){
/* ... */
};
此外,您可以为 PyQuaternionType 定义自己的 C-API,从而允许您从 Quaternions 创建 PyQuaternions
static PyObject *
PyQuaternion_New(Quaternion *q){
PyQuaternion *self;
self = (PyQuaternion *)PyQuaternion_Type.tp_new(type, NULL, NULL);
self->q = q;
return (PyObject *)self;
}
请注意self->q 将由PyQuaternion_dealloc 函数处理,因此请考虑内存管理。最简单的方法是将所有权传递给包装器并让PyQuaternion_dealloc 释放self->q。
PyQuaternion_New 函数允许您包装Quaternion 对象并将它们填充到任何python 容器中,例如列表、元组,当然还有带有dtype = numpy.object 的numpy 数组。