问题描述
我在Python扩展模块中有一个函数 foo
,该函数应该将int元组返回给Python.使用 Py_BuildValue
:
I have a function foo
in a Python Extension Module that should return a tuple of ints to Python. This can be easily done using Py_BuildValue
:
static PyObject*
foo(PyObject* self, PyObject* args)
{
int a = 0;
int b = 0;
/* calculations and stuff */
PyObject* out = Py_BuildValue("(iii)", a, b, a+b);
Py_INCREF(out);
return out;
}
我要使用 PyTuple_Pack
而不是 Py_BuildValue
,这可以确保返回值确实是一个元组.
Instead of Py_BuildValue
, I want to use PyTuple_Pack
, which ensures that the return value is indeed a tuple.
Python C API文档说, PyTuple_Pack(3,a,b,a + b)
等效于 Py_BuildValue((iii)",a,b,a + b)
.这两个函数均返回类型为 PyPbject *
的新引用.
The Python C API documentation says that PyTuple_Pack(3, a, b, a+b)
is equivalent to Py_BuildValue("(iii)", a, b, a+b)
. Both functions return a new reference of type PyPbject*
.
因此,鉴于上面的代码,
Hence, given the code above,
static PyObject*
foo(PyObject* self, PyObject* args)
{
/* ... */
PyObject* out = PyTuple_Pack(3, a, b, a+b);
Py_INCREF(out);
return out;
}
应该可以解决这个问题,而事实并非如此.相反,我遇到了段错误.我在这里想念什么?
should do the trick, which is does not. Instead I get a segfault.What am I missing here?
推荐答案
区别是:
-
Py_BuildValue((ii)",a,b)
期望a
和b
是简单的C-int值. -
PyTuple_Pack(2,a,b)
期望a
和b
已经是PyObject
s(和不是C-ints.)
Py_BuildValue("(ii)", a, b)
expectsa
andb
to be simple C-int values.PyTuple_Pack(2, a, b)
expectsa
andb
to be alreadyPyObject
s (and not C-ints).
文档说:
要使用 PyTuple_Pack
,您需要先将int值转换为Python-Integers.
In order to use PyTuple_Pack
you need to convert the int-values to Python-Integers first.
使用 Py_BuildValue()
更简单.如果您在 Py_BuildValue
,结果将是一个元组:
It is simpler to use
Py_BuildValue()
. If you parenthesize your format string in Py_BuildValue
, the result will be a tuple:
这意味着:如果您至少由两个元素构成一个元组,则无需担心:
That means: there is nothing to worry about if you construct a tuple from at least two elements:
Py_BuildValue("ii", a, b) # returns a tuple
Py_BuildValue("(ii)", a, b) # returns a tuple
只有一个元素会有所不同:
It is different if there is only one element:
Py_BuildValue("i", a) # returns an integer
# parenthesized:
Py_BuildValue("(i)", a) # returns a tuple with an integer
或完全没有元素:
Py_BuildValue("") # returns None
# parenthesized:
Py_BuildValue("()") # returns an empty tuple.
因此,只需确保格式字符串中有括号,并且返回的值将是元组.
So just make sure there are parenthesizes in the format string and the returned value will be a tuple.
这篇关于PyTuple_Pack段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!