我是Python C-API的新手,正在浏览一些源代码以挑选其中的一部分。
这里是我在包含扩展模块的程序包的C源代码中找到的函数的最低版本:
#define PY_SSIZE_T_CLEAN
#include <Python.h>
static PyObject *
modulename_myfunc(PyObject *self, PyObject *args) {
// Call PyArg_ParseTuple, etc ...
// Dummy values; in the real function they are calculated
int is_found = 1;
Py_ssize_t n_bytes_found = 1024;
PyObject *result;
result = Py_BuildValue("(Oi)",
is_found ? Py_True : Py_False, // Py_INCREF?
n_bytes_found);
return result;
}
这是否通过在Py_INCREF
或Py_True
上不使用Py_False
引起了小的内存泄漏? C-API docs for Boolean object似乎很明确,总是需要增加/拒绝Py_True
和Py_False
。
如果确实需要引入Py_INCREF
,假设Py_RETURN_TRUE
/ Py_RETURN_FALSE
因为返回了元组而实际上并不适用,那么如何在这里最合适地使用它?
此处未使用Py_INCREF
的原因是,Py_BuildValue
在传递给对象时带有“ O”将为您增加引用计数:
O(对象)[PyObject *]
[传递Python对象时保持不变(其引用计数增加一,但引用计数除外)。如果传入的对象是NULL指针,则认为这是由于产生该参数的调用发现错误并设置异常而引起的。因此,Py_BuildValue()将返回NULL,但不会引发异常。如果尚未引发异常,则设置SystemError。
例如,您将在CPython Py_BuildValue
中看到类似的用法。