kyn*_*nan 12 c python swig struct cython
我想访问一个C函数,它返回一个包含double数组的结构(其中这些数组的长度由结构的其他int成员给出)来自python.声明是
typedef struct {
int dim;
int vertices;
int quadrature_degree;
int polynomial_degree;
int ngi;
int quadrature_familiy;
double *weight; /* 1D: ngi */
double *l; /* 2D: ngi * dim */
double *n; /* 2D: ngi * vertices */
double *dn; /* 3D: ngi * vertices * dim */
} element;
extern void get_element(int dim, int vertices, int quad_degree, int poly_degree, element* e);
Run Code Online (Sandbox Code Playgroud)
重要的是我希望能够以double*
正确形状的NumPy数组访问所有成员(即dn
应该可以作为3D数组访问).
简单地SWIG包装这给了我很好的结构,但所有double*
成员都<Swig Object of type 'double *' at 0x348c8a0>
使它们无用.我玩过NumPy SWIG接口文件,但无法使任何类型的图像( DATA_TYPE* INPLACE_ARRAY1, int DIM1 )
工作(我认为在这种情况下不可能让它们匹配,但我很高兴被证明是错误的).
我的猜测是我必须PyArrayObject
为这些成员处理NumPy数组的代码初始化,而SWIG扩展我的结构以使它们可以在Python中访问?这看起来很多工作.任何人都可以看到使用SWIG更好的方式吗?如果这样可以更容易,那么可以更改结构或返回它的方法.
或者,我看了一下cython和ctypes.这些更适合我想要实现的目标吗?我没有使用过cython,所以无法判断它的包装能力.对于ctypes,我可以大致想象一下如何做,但这意味着手工编写我希望合理自动化的包装器可以为我做的事情.
任何建议都感激不尽!
Cython规则:
cdef extern from "the header.h":
ctypedef struct element:
int dim
int vertices
int quadrature_degree
int polynomial_degree
int ngi
int quadrature_familiy
double *weight
double *l
double *n
double *dn
void get_element(int dim, int vertices, int quad_degree, int poly_degree, element* e)
Run Code Online (Sandbox Code Playgroud)
然后你可以从python空间接口它
使用SWIG需要整个结构的类型映射.只有指针成员的Tyepmaps是不够的,因为它们没有上下文来知道初始化NumPy数组的大小.我设法得到了我想要的以下类型图(基本上是从numpy.i复制和粘贴并适应我的需求,可能不是很强大):
%typemap (in,numinputs=0) element * (element temp) {
$1 = &temp;
}
%typemap (argout) element * {
/* weight */
{
npy_intp dims[1] = { $1->ngi };
PyObject * array = PyArray_SimpleNewFromData(1, dims, NPY_DOUBLE, (void*)($1->weight));
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,array);
}
/* l */
{
npy_intp dims[2] = { $1->ngi, $1->dim };
PyObject * array = PyArray_SimpleNewFromData(2, dims, NPY_DOUBLE, (void*)($1->l));
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,array);
}
/* n */
{
npy_intp dims[2] = { $1->ngi, $1->vertices };
PyObject * array = PyArray_SimpleNewFromData(2, dims, NPY_DOUBLE, (void*)($1->n));
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,array);
}
/* dn */
{
npy_intp dims[3] = { $1->ngi, $1->vertices, $1->dim };
PyObject * array = PyArray_SimpleNewFromData(3, dims, NPY_DOUBLE, (void*)($1->dn));
if (!array) SWIG_fail;
$result = SWIG_Python_AppendOutput($result,array);
}
}
Run Code Online (Sandbox Code Playgroud)
这与C函数的不同之处在于它返回一个带有我想要的数据的NumPy数组元组,这比element
以后从对象中提取它更方便.第一个类型图还消除了传递类型对象的需要element
.因此,我可以element
完全从python用户隐藏结构.
python接口最终看起来像这样:
weight, l, n, dn = get_element(dim, vertices, quadrature_degree, polynomial_degree)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3587 次 |
最近记录: |