numpy 数据类型c++ 底层实现

c++ 使用numpy 数据类型

  • 解决c++ 想使用numpy 底层数据结构
  • python 层想使用c++ 数据结构
#include <numpy/ndarrayobject.h>
#include <numpy/ufuncobject.h>
#include <numpy/npy_3kcompat.h>

//定义c ++ 数据类型
typedef struct 
{
    Value v;
}data;
//定义python 数据类型
typedef struct 
{
    PyObject_HEAD;
	data v;
}py_data;
//定义python 数据成员
PyMemberDef py_data_member[] = {
	{"v",T_INT,offsetof(py_data,v.v),READONLY,"v"},
	{NULL}
};
PyTypeObject py_data_type_type = {
	#if defined(NPY_PY3K)
	PyVarObject_HEAD_INIT(NULL, 0)
#else
	PyObject_HEAD_INIT(NULL)
	0,                                          /* ob_size */
#endif
	"py_data",
	sizeof(py_data),
	0,                                          /* tp_itemsize */
	0,                                          /* tp_dealloc */
	0,                                          /* tp_print */
	0,                                          /* tp_getattr */
	0,                                          /* tp_setattr */
#if defined(NPY_PY3K)
	0,                                          /* tp_reserved */
#else
	0,                                          /* tp_compare */
#endif
	0,                                          /* tp_repr */
	0,                                          /* tp_as_number */
	0,                                          /* tp_as_sequence */
	0,                                          /* tp_as_mapping */
	0,                                          /* tp_hash */
	0,                                          /* tp_call */
	0,                                          /* tp_str */
	0,                                          /* tp_getattro */
	0,                                          /* tp_setattro */
	0,                                          /* tp_as_buffer */
	0,                                          /* tp_flags */
	0,                                          /* tp_doc */
	0,                                          /* tp_traverse */
	0,                                          /* tp_clear */
	0,                                          /* tp_richcompare */
	0,                                          /* tp_weaklistoffset */
	0,                                          /* tp_iter */
	0,                                          /* tp_iternext */
	0,                                          /* tp_methods */
	py_signal_type_member,						/* tp_members */
};
static PyObject *type_getitem(char *ip, PyArrayObject* ap)
{
	PyTypeObject* type = (PyTypeObject*)&py_data_type_type;
	py_data *self = (py_data*)type->tp_alloc(type, 0);
	self->v = *((data*)ip);
	return (PyObject *)self;
}
static void type_copyswapn(void*dst, npy_intp dstride, void* src, npy_intp sstride,
                           npy_intp n, int swap, void *NPY_UNUSED(arr))
{
	return;
}
static void data_copyswap(void *dst, void* src, int swap, void* NPY_UNUSED(arr))
{
	if (!src)
		return;
	data *sig = (data*)dst;
	memcpy(sig, src, sizeof(data));
}

static int type_setitem(PyObject* op, char *ov, PyArrayObject* ap)
{
	return 0;
}

static npy_bool type_nonzero(char *ip, PyArrayObject* ap)
{
	return (npy_bool)true;
}

//直接拿着返回的数值就可以创建一个numpy 数组了。 在python 层也能返回numpy array 直接进行使用
static int register_numpy_dtype()
{
	if (PyType_Ready(&py_data_type_type) < 0) {
		PyErr_Print();
		PyErr_SetString(PyExc_SystemError, "could not initialize py_data_type_type");
		return -1;
	}
	
	int type_num = 0;
	static PyArray_ArrFuncs _PyDataType_ArrFuncs;
	PyArray_InitArrFuncs(&_PySignalType_ArrFuncs);
	_PyDataType_ArrFuncs.getitem = (PyArray_GetItemFunc *)type_getitem;
	_PyDataType_ArrFuncs.setitem = (PyArray_SetItemFunc *)type_setitem;
	_PyDataType_ArrFuncs.copyswap = (PyArray_CopySwapFunc *)data_copyswap;
	_PyDataType_ArrFuncs.copyswapn = (PyArray_CopySwapNFunc *)type_copyswapn;
	_PyDataType_ArrFuncs.nonzero = (PyArray_NonzeroFunc *)type_nonzero;
	
	PyArray_Descr *data_descr;
	signal_descr = PyObject_New(PyArray_Descr, &PyArrayDescr_Type);
	signal_descr->typeobj = &py_data_type_type;
	signal_descr->kind = 'q';
	signal_descr->type = 'j';
	signal_descr->byteorder = '=';
	signal_descr->type_num = 0;
	signal_descr->elsize = sizeof(data);
	signal_descr->alignment = 8;
	signal_descr->subarray = NULL;
	signal_descr->fields = NULL;
	signal_descr->names = NULL;
	signal_descr->f = &_PyDataType_ArrFuncs;
	Py_INCREF(&py_data_type_type);
	type_num = PyArray_RegisterDataType(signal_descr);
	if (type_num < 0)
	{
		PyErr_SetString(PyExc_SystemError, "could not initialize py_data_type_type");
		return -1;
	}
	return 0;
}


posted @ 2021-03-11 17:16  boht  阅读(1520)  评论(0编辑  收藏  举报