我试图在Python应用程序中包装库中的一些第三方代码。实际上,我想调用的函数以一个结构作为输入,其中包含指向双数组的指针。一个简单的例子是:
我的功能:
typedef struct mystruct_t {
int n;
double *x;
} mystruct_t;
double myfunc(mystruct_t* data);
myfunc.c:
^{pr2}$生成文件:
CC = gcc
CFLAGS = -g -Wall -fPIC -lm -std=gnu99
all: libmyfunc.so
m.PHONY : clean
libmyfunc.so: myfunc.o
gcc -shared -Wl,-soname,$@ -o $@ $^
%.o: %.c
$(CC) -c $(CFLAGS) $<
clean:
rm -vf libmyfunc.so *.o
我想用NumPy、ctypes.Structure
和numpy.ctypeslib
来包装{mystruct_t
的属性传递给myfunc
。到目前为止,我一直在尝试以下方法:
我的函数.py:
#!/usr/bin/env python
import numpy as np
import numpy.ctypeslib as npct
import ctypes
import os
array_1d_double = npct.ndpointer(dtype=np.double, ndim=1, flags='C_CONTIGUOUS')
class MyStruct(ctypes.Structure):
_fields_ = [
('n', ctypes.c_int16),
('x', array_1d_double)
]
libmyfunc = npct.load_library('libmyfunc', os.path.dirname(__file__))
libmyfunc.myfunc.restype = ctypes.c_double
libmyfunc.myfunc.argtypes = [
ctypes.POINTER(MyStruct)
]
x = np.array([1.0, 2.0, 3.0, 4.0])
mystruct = MyStruct()
mystruct.n = len(x)
mystruct.x = x
res = libmyfunc.myfunc(mystruct)
但是,此操作失败,并显示以下错误消息:
$ python myfunc.py
Traceback (most recent call last):
File "./myfunc.py", line 26, in <module>
mystruct.x = x
TypeError: cannot be converted to pointer
如何正确定义函数签名以便进行类型转换?或者,在将x
分配给mystruct.x
之前,我是否需要转换它?在
不幸的是,我不能更改我想调用的方法的签名,并且我希望不必编写包装器C代码,除非这是绝对必要的。我在这方面发现的其他问题和资源只处理ctypes.Structure
s或{
我已经上传了我的简化示例as a gist,因此您可以使用它作为起点。在
先谢谢你!在
您可以删除
array_1d_double
。这是不需要的。在结构应如下声明:
两种类型我都换了。您有
c_int16
,但是在C代码中使用的类型是int
。映射到c_int
。同样地,对于数组,double*
。在ctypes中是POINTER(ctypes.c_double)
。在应按如下方式初始化结构:
^{pr2}$通过这些更改,您的代码可以按预期工作。在
相关问题 更多 >
编程相关推荐