使用 Ctypes 和 Python.h 将列表从 Python 传递到 C
Pass a list from Python to C with Ctypes and Python.h
我正在尝试将空的 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 文档中的错误并不感到惊讶:
As has been mentioned before, all Python types except integers,
strings, and unicode strings have to be wrapped in their corresponding
ctypes type, so that they can be converted to the required C data
type
有办法解决这个问题吗?我看不到列表的 ctype。
我基本上想要一个 C 函数在调用时会为我修改的列表。如果我在 C 函数中通过引用传递一个值并修改它,它会如何工作,它会修改原始值。
您可以将 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)
调用会(很可能)使程序崩溃。
我正在尝试将空的 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 文档中的错误并不感到惊讶:
As has been mentioned before, all Python types except integers, strings, and unicode strings have to be wrapped in their corresponding ctypes type, so that they can be converted to the required C data type
有办法解决这个问题吗?我看不到列表的 ctype。
我基本上想要一个 C 函数在调用时会为我修改的列表。如果我在 C 函数中通过引用传递一个值并修改它,它会如何工作,它会修改原始值。
您可以将 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)
调用会(很可能)使程序崩溃。