在 C++ 中嵌入 Python 时无法将参数传递给 Python 函数
Can't pass arguments to Python function while embedding Python in C++
我在我的 C++ 代码中嵌入了一个 Python 模块,并且我正在使用 Python/C API。
我需要调用 Python 模块函数并获取结果。
该函数获取一个无符号整数和一个双精度数作为输入参数并输出一个列表。
我使用以下调用函数:
unsigned int num_units = 10;
double max_time = 15.12;
PyObject *output_list = PyObject_CallMethod(sample_object, "get_list",
"(I)", num_units, "(d)", max_time);
在 get_list
函数中添加打印语句时,我从 Python 方面注意到的是参数没有传递给函数。
我想我的语法可能不正确?
更新:
我最初使用以下语法尝试了@Ruzihm 的建议,但没有成功。事实证明,python 代码中还有其他语法问题阻止了代码的正确执行,我的错误检查 none 发现了它。修复问题后,代码 运行 完美无缺。
PyObject *output_list = PyObject_CallMethod(sample_object, "get_list",
"Id",num_units, max_time);
我还尝试将 CallMethodObjArgs 与以下代码一起使用,效果也很好:
PyObject *func_obj, *num_units_obj, *max_time_obj;
num_units_obj = PyLong_FromUnsignedLong(num_units);
max_time_obj = PyFloat_FromDouble(max_time);
func_obj = PyUnicode_FromString("get_list");
PyObject *output_list = PyObject_CallMethodObjArgs(sample_object,
func_obj, num_units_obj,
max_time_obj, NULL);
Py_DECREF(func_obj);
Py_DECREF(num_units_obj);
Py_DECREF(max_time_obj);
Python 函数定义也如下所示:
def get_list(self, num_units, max_time):
非常感谢任何帮助。
应该只有一个格式字符串(可能为 NULL)后跟 any/all 输入。括号用于指定大小为零或一的元组,您没有提到需要。所以,就这样做:
PyObject *output_list = PyObject_CallMethod(sample_object,
"get_list", "Id", num_units, max_time);
完整示例:
foobar.py
class foobar():
def get_list(self, num_units, max_time):
print(num_units)
print(max_time)
foobar.cpp
#define PY_SSIZE_T_CLEAN
#include "python3.6m/Python.h"
#include <iostream>
int main() {
PyObject *module, *dict, *python_class, *sample_object;
setenv("PYTHONPATH", ".", 1);
Py_Initialize();
module = PyImport_ImportModule("foobar");
if (module == nullptr)
{
std::cout << "Failed to import module.";
return 1;
}
dict = PyModule_GetDict(module);
if (dict == nullptr)
{
std::cout << "Failed to get module dict.";
return 1;
}
Py_DECREF(module);
python_class = PyDict_GetItemString(dict, "foobar");
if (python_class == nullptr)
{
std::cout << "Failed to get class.";
return 1;
}
Py_DECREF(dict);
sample_object = PyObject_CallObject(python_class, nullptr);
if (sample_object == nullptr)
{
std::cout << "Failed to instantiate object.";
return 1;
}
Py_DECREF(python_class);
unsigned int num_units = 10;
double max_time = 15.12;
PyObject *output_list = PyObject_CallMethod(sample_object, "get_list",
"Id", num_units, max_time);
/* Alternatively, use PyObject_CallMethodObjArgs
PyObject *func_obj, *num_units_obj, *max_time_obj;
num_units_obj = PyLong_FromUnsignedLong(num_units);
max_time_obj = PyFloat_FromDouble(max_time);
func_obj = PyUnicode_FromString("get_list");
PyObject *output_list = PyObject_CallMethodObjArgs(sample_object,
func_obj, num_units_obj,
max_time_obj, NULL);
Py_DECREF(func_obj);
Py_DECREF(num_units_obj);
Py_DECREF(max_time_obj);
*/
}
(基于 代码)
输出
$ g++ foobar.cpp -lpython3.6m;./a.out
10
15.12
我在我的 C++ 代码中嵌入了一个 Python 模块,并且我正在使用 Python/C API。 我需要调用 Python 模块函数并获取结果。 该函数获取一个无符号整数和一个双精度数作为输入参数并输出一个列表。 我使用以下调用函数:
unsigned int num_units = 10;
double max_time = 15.12;
PyObject *output_list = PyObject_CallMethod(sample_object, "get_list",
"(I)", num_units, "(d)", max_time);
在 get_list
函数中添加打印语句时,我从 Python 方面注意到的是参数没有传递给函数。
我想我的语法可能不正确?
更新: 我最初使用以下语法尝试了@Ruzihm 的建议,但没有成功。事实证明,python 代码中还有其他语法问题阻止了代码的正确执行,我的错误检查 none 发现了它。修复问题后,代码 运行 完美无缺。
PyObject *output_list = PyObject_CallMethod(sample_object, "get_list",
"Id",num_units, max_time);
我还尝试将 CallMethodObjArgs 与以下代码一起使用,效果也很好:
PyObject *func_obj, *num_units_obj, *max_time_obj;
num_units_obj = PyLong_FromUnsignedLong(num_units);
max_time_obj = PyFloat_FromDouble(max_time);
func_obj = PyUnicode_FromString("get_list");
PyObject *output_list = PyObject_CallMethodObjArgs(sample_object,
func_obj, num_units_obj,
max_time_obj, NULL);
Py_DECREF(func_obj);
Py_DECREF(num_units_obj);
Py_DECREF(max_time_obj);
Python 函数定义也如下所示:
def get_list(self, num_units, max_time):
非常感谢任何帮助。
应该只有一个格式字符串(可能为 NULL)后跟 any/all 输入。括号用于指定大小为零或一的元组,您没有提到需要。所以,就这样做:
PyObject *output_list = PyObject_CallMethod(sample_object,
"get_list", "Id", num_units, max_time);
完整示例:
foobar.py
class foobar():
def get_list(self, num_units, max_time):
print(num_units)
print(max_time)
foobar.cpp
#define PY_SSIZE_T_CLEAN
#include "python3.6m/Python.h"
#include <iostream>
int main() {
PyObject *module, *dict, *python_class, *sample_object;
setenv("PYTHONPATH", ".", 1);
Py_Initialize();
module = PyImport_ImportModule("foobar");
if (module == nullptr)
{
std::cout << "Failed to import module.";
return 1;
}
dict = PyModule_GetDict(module);
if (dict == nullptr)
{
std::cout << "Failed to get module dict.";
return 1;
}
Py_DECREF(module);
python_class = PyDict_GetItemString(dict, "foobar");
if (python_class == nullptr)
{
std::cout << "Failed to get class.";
return 1;
}
Py_DECREF(dict);
sample_object = PyObject_CallObject(python_class, nullptr);
if (sample_object == nullptr)
{
std::cout << "Failed to instantiate object.";
return 1;
}
Py_DECREF(python_class);
unsigned int num_units = 10;
double max_time = 15.12;
PyObject *output_list = PyObject_CallMethod(sample_object, "get_list",
"Id", num_units, max_time);
/* Alternatively, use PyObject_CallMethodObjArgs
PyObject *func_obj, *num_units_obj, *max_time_obj;
num_units_obj = PyLong_FromUnsignedLong(num_units);
max_time_obj = PyFloat_FromDouble(max_time);
func_obj = PyUnicode_FromString("get_list");
PyObject *output_list = PyObject_CallMethodObjArgs(sample_object,
func_obj, num_units_obj,
max_time_obj, NULL);
Py_DECREF(func_obj);
Py_DECREF(num_units_obj);
Py_DECREF(max_time_obj);
*/
}
(基于
输出
$ g++ foobar.cpp -lpython3.6m;./a.out
10
15.12