【发布时间】:2019-10-21 13:22:37
【问题描述】:
我想要
- 用c写一个函数
sum_list对一个列表求和,命名为sum_list.c - 将
sum_list.c文件制作成sum_list.so sum_list = ctypes.CDLL('./sum_list.so')result = sum_list.sum_list([1, 2, 3])
它在第 4 步中引发错误:
ctypes.ArgumentError: 参数 1: : 不知道如何 转换参数1
当我在 c 中编写一个添加两个数字的函数时,它可以正常工作。
所以,关键是我不知道如何将列表(python 对象)传递给 c。
sum_list.c
#define PY_SSIZE_T_CLEAN
#include <Python.h>
long sum_list(PyObject *list)
{
Py_ssize_t i, n;
long total = 0, value;
PyObject *item;
n = PyList_Size(list);
if (n < 0)
return -1; /* Not a list */
for (i = 0; i < n; i++) {
item = PyList_GetItem(list, i); /* Can't fail */
if (!PyLong_Check(item)) continue; /* Skip non-integers */
value = PyLong_AsLong(item);
if (value == -1 && PyErr_Occurred())
/* Integer too big to fit in a C long, bail out */
return -1;
total += value;
}
return total;
}
python 代码
from ctypes import CDLL
sum_list = CDLL('./sum_list.so')
l = [1, 2, 3]
sum_list.sum_list(l)
我希望我的 python 代码中的
var结果是6。
【问题讨论】:
-
PyList_GetItem(list, i); /* Can't fail */实际上是错误的。 It can fail - 特别是如果列表在迭代期间由于某种原因改变了大小。可能很难推断它没有! -
如果它失败了,你的代码也会失败。
-
@AnttiHaapala 我想我明白了原因...我从docs.python.org/3/c-api/intro.html#coding-standards 复制代码你能展示一些关于地址传递如何可能的简短演示吗?
-
@kun 请不要忘记回来投票/接受对您有帮助的答案。这就是我们在这里说“谢谢”的方式。
标签: python c python-3.x ctypes