C++调用Python多返回值时PyArg_Parse的正确使用格式
问题背景
我在C++中使用PyObject_CallObject调用Python代码。
当Python函数仅返回一个浮点数时,我可以通过如下代码获取返回值:
float output_of_python; PyObject *pValue,*pArgs; pValue = PyObject_CallObject(pFunc, pArgs); PyArg_Parse(pValue, "f", &output_of_python);
但如果Python函数返回2个值(即return first,second的写法),应当使用什么格式的PyArg_Parse(pValue...)调用,才能将两个返回值分别赋值给两个C++ float类型变量?
补充说明:以下写法经测试无法正常工作:
PyArg_Parse(pValue, "f,f", &output_of_python1,&output_of_python2);
问题原因
Python中return first, second语法本质是返回包含两个浮点元素的tuple(元组)对象,并非两个独立浮点数。"f,f"格式串要求解析函数从参数列表依次读取两个独立浮点类型对象,而传入的pValue是单个元组对象,和格式要求不匹配,因此解析失败。
正确写法
使用(ff)作为格式串即可,这个格式的语义是:将当前传入的对象解析为包含两个float元素的元组,依次把两个元素的值写入对应的C++变量地址。
示例代码:
float output_of_python1, output_of_python2; PyObject *pValue, *pArgs; pValue = PyObject_CallObject(pFunc, pArgs); // 解析返回的二元组 if (!PyArg_Parse(pValue, "(ff)", &output_of_python1, &output_of_python2)) { // 解析失败时的错误处理逻辑:比如打印Python异常栈、清理已申请资源 Py_DECREF(pValue); return -1; } // 后续业务逻辑直接使用output_of_python1、output_of_python2即可 // ... // 用完Python对象必须减少引用计数,避免内存泄漏 Py_DECREF(pValue);
额外注意事项
- 不要省略解析结果校验:如果
PyArg_Parse返回0,说明类型不匹配或者Python函数执行抛出了异常,需要及时处理,避免后续逻辑崩溃 - 如果需要更高的鲁棒性,可以在解析前先用
PyTuple_Check(pValue)判断返回值是否确实为元组,再做后续操作 - 所有通过Python C API拿到的
PyObject*对象,在不再使用时都要正确调用Py_DECREF释放引用,否则会造成内存泄漏
内容的提问来源于stack exchange,提问作者abcd
相关产品推荐
相关产品推荐

