使用 Python C API 将 Python 整数列表传递给 C 函数

Posted

技术标签:

【中文标题】使用 Python C API 将 Python 整数列表传递给 C 函数【英文标题】:Pass Python list of ints to C function using Python C API 【发布时间】:2018-06-27 22:33:04 【问题描述】:

我在使用 MacOS High Sierra 上的 Python3.6 anaconda 发行版处理传递给 Python C API 包装函数的整数列表时遇到问题。我想将传入的整数列表转换为可以在 C 中使用的整数数组。

Passing a Python list to C function using the Python/C API 这里有一个类似的问题,我可以开始工作,但处理整数列表似乎有所不同。

这是我目前所拥有的。

static PyObject * myModule_sumIt(PyObject *self, PyObject *args) 
  PyObject *lst; 
  if(!PyArg_ParseTuple(args, "O", &lst)) 
    Py_DECREF(lst);
    return NULL;
  

  int n = PyObject_Length(lst);
  printf("\nLength of list passed in is %d\n", n);

  int nums[n];
  int sum = 0;
  for (int i = 0; i < n; i++) 
     PyLongObject *item = PyList_GetItem(lst, i);
     sum += item;
     printf("\ni = %d\titem = %d\tsum = %d\n", i, item, sum);
     Py_DECREF(item);
  

  Py_DECREF(lst);
  return Py_BuildValue("i", sum);


static PyMethodDef methods[] = 
   "sum_it", myModule_sumIt, METH_VARARGS, "A Toy Example" ,
   NULL, NULL, 0, NULL 
;

static struct PyModuleDef myModule = 
  PyModuleDef_HEAD_INIT,
  "myModule", 
  "Demo Python wrapper",
  -1,
  methods
;

PyMODINIT_FUNC PyInit_myModule(void) 
  return PyModule_Create(&myModule);

这是我在使用 distutils 构建后在解释器中调用 python 函数得到的结果。

>>> import myModule
>>> myModule.sum_it([1,2,3])
Length of list passed in is 3
i = 0   item = 108078416    sum = 890306742
i = 1   item = 108078448    sum = 890306742
i = 2   item = 108078480    sum = 890306742
-1725230192

请注意,我的预期输出应该是

>>> import myModule
>>> myModule.sum_it([1,2,3])
Length of list passed in is 3
i = 0   item = 1    sum = 1
i = 1   item = 2    sum = 3
i = 2   item = 3    sum = 6
6

【问题讨论】:

【参考方案1】:
sum += item;

item 不是 C long 或 int!你必须使用PyLong_AsLong:

sum += PyLong_AsLong(item);

(而sum 应该是long

【讨论】:

以上是关于使用 Python C API 将 Python 整数列表传递给 C 函数的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 Python/C API 将 Python 实例传递给 C++

Python / C-Api:向模块添加类

具有递归的 Python C API - 段错误

Python C API和数据持久化在内存中?

python c api无法将任何模块导入新创建的模块

Python C API - 创建关键字