Since Quaternion
is not directly a numeric type, your array must have numpy.object
as dtype
. Hence, you can use PyArray_SimpleNew(..., NPY_OBJECT)
to create an array and fill in the data.
The problem is that your Quaternion
class is not a python type. So filling the array with references to objects of type Quaternion
will not work. (In this case, what would you expect to happen, if you extract an element from the array filled with quaternions from python?)
Instead, you need to wrap the Quaternion
class with something like PyQuaternion
. The wrapper takes care of reference counts and memory management. It will look something like:
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){
/* ... */
};
Furthermore you can define your own C-API for the PyQuaternionType
allowing you to create PyQuaternions
from Quaternions
static PyObject *
PyQuaternion_New(Quaternion *q){
PyQuaternion *self;
self = (PyQuaternion *)PyQuaternion_Type.tp_new(type, NULL, NULL);
self->q = q;
return (PyObject *)self;
}
Be aware that self->q
will be handled by the PyQuaternion_dealloc
function, so think about the memory management. The simplest would be to pass ownership to the wrapper and let PyQuaternion_dealloc
deallocate self->q
.
The PyQuaternion_New
function allows you to wrap Quaternion
objects and fill them in to any python container, like lists, tuples and of course also numpy arrays with dtype = numpy.object
.