我正在尝试将空result
列表传递给C函数,该函数可以在以后的Python中修改和使用。这是我想要做的:
filename = askopenfilename()
result = []
status = self.lib.Cal_readFile(filename, result)
filename
参数没问题,但是传递结果变量我得到错误:
status = self.lib.Cal_readFile(filename, result)
ctypes.ArgumentError: argument 2: <class 'TypeError'>: Don't know how to convert parameter 2
我对ctypes文档声明的错误并不感到惊讶:
如前所述,除了整数之外的所有Python类型, 字符串和unicode字符串必须包装在它们对应的字符串中 ctypes类型,以便它们可以转换为所需的C数据 型
有没有办法解决这个问题?我看不到列表的ctype。
我基本上想要一个C函数在调用时会为我修改的列表。如果我通过引用C函数中的值并对其进行修改,它将会修改原始值。
答案 0 :(得分:3)
您可以将ctypes.pydll
与ctypes.py_object
一起用作参数类型,以允许传递本机Python对象。
这是一个最小的例子:
test.c
#include <Python.h>
extern int length(PyObject *obj)
{
return PyObject_Length(obj);
}
这是使用它的Python代码:
>>> lib = ctypes.pydll.LoadLibrary('./test.so')
>>> lib.length.argtypes = [ctypes.py_object]
>>> lib.length([1,2,3])
3
>>> lib.length(None)
Traceback (most recent call last):
File "<pyshell#85>", line 1, in <module>
lib.length(None)
TypeError: object of type 'NoneType' has no len()
如果您在C代码中使用Python API,则必须使用ctypes.pydll
而不是ctypes.cdll
。这可以防止GIL被释放,并允许您安全地在C代码中调用Python API函数。否则,lib.length(None)
调用会(可能)使程序崩溃。