C++调用Python(执行Python文件)的全过程可以分为以下步骤:
- 确定Python环境
在开始前,需要确保正确设置了Python环境变量,并且已经正确安装了所需要的Python包(例如numpy、pandas等)。
- 编写Python代码
在C++中调用Python时,需要事先编写好Python代码,并将其保存为.py文件。Python代码中必须定义一些函数或者类,供C++调用。例如:
# example.py
def add(a, b):
return a + b
上述代码定义了一个名为“add”的函数,该函数可以接受两个参数,并返回它们的和。这个函数就是Python所提供给C++使用的接口。
- 调用Python脚本
为了从C++中调用Python,我们需要使用Python提供的API。其中,最主要的API函数是Py_Initialize和PyRun_SimpleString。
#include <Python.h>
int main() {
// 初始化Python环境
Py_Initialize();
// 调用Python脚本
PyRun_SimpleString("import example\nresult = example.add(1, 2)\nprint(result)");
// 关闭Python环境
Py_Finalize();
return 0;
}
上述代码通过调用Py_Initialize函数来初始化Python环境,然后调用PyRun_SimpleString函数来执行Python脚本。在这个例子中,我们导入了例子中定义的Python模块,并调用其中的add函数,并将结果输出到标准输出流中。
- 嵌入Python环境
如果我们需要从C++中调用Python函数,可以通过Python提供的API函数来实现。
#include <Python.h>
int main() {
// 初始化Python环境
Py_Initialize();
// 加载Python脚本
FILE* fp = _Py_fopen("example.py", "r");
PyRun_SimpleFile(fp, "example.py");
fclose(fp);
// 导入Python模块
PyObject* pModule = PyImport_ImportModule("example");
// 获取Python函数对象
PyObject* pFunc = PyObject_GetAttrString(pModule, "add");
// 设置Python函数参数
PyObject* pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs, 0, PyLong_FromLong(1));
PyTuple_SetItem(pArgs, 1, PyLong_FromLong(2));
// 调用Python函数
PyObject* pResult = PyObject_CallObject(pFunc, pArgs);
// 获取Python函数返回值
int result = (int) PyLong_AsLong(pResult);
printf("%d", result);
// 释放Python对象
Py_DECREF(pArgs);
Py_DECREF(pResult);
Py_DECREF(pFunc);
Py_DECREF(pModule);
// 关闭Python环境
Py_Finalize();
return 0;
}
上述代码通过调用PyImport_ImportModule函数导入Python模块,并通过PyObject_GetAttrString函数获取其中的add函数。然后,通过PyTuple_New和PyTuple_SetItem函数设置函数参数,并通过PyObject_CallObject函数调用add函数并获取其返回值。
示例1:计算两个数的平均值
Python代码:
# average.py
def average(a, b):
return (a + b) / 2
C++代码:
#include <Python.h>
int main() {
// 初始化Python环境
Py_Initialize();
// 加载Python脚本
FILE* fp = _Py_fopen("average.py", "r");
PyRun_SimpleFile(fp, "average.py");
fclose(fp);
// 导入Python模块
PyObject* pModule = PyImport_ImportModule("average");
// 获取Python函数对象
PyObject* pFunc = PyObject_GetAttrString(pModule, "average");
// 设置Python函数参数
PyObject* pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs, 0, PyLong_FromLong(1));
PyTuple_SetItem(pArgs, 1, PyLong_FromLong(3));
// 调用Python函数
PyObject* pResult = PyObject_CallObject(pFunc, pArgs);
// 获取Python函数返回值
double result = PyFloat_AsDouble(pResult);
printf("%f", result);
// 释放Python对象
Py_DECREF(pArgs);
Py_DECREF(pResult);
Py_DECREF(pFunc);
Py_DECREF(pModule);
// 关闭Python环境
Py_Finalize();
return 0;
}
示例2:使用Python脚本进行图像处理
Python代码:
# image.py
from PIL import Image
import os
def resize_image(file_in, file_out, size=(128, 128)):
with Image.open(file_in) as im:
im.thumbnail(size)
im.save(file_out, "JPEG")
return os.path.getsize(file_out)
C++代码:
#include <Python.h>
int main() {
// 初始化Python环境
Py_Initialize();
// 加载Python脚本
FILE* fp = _Py_fopen("image.py", "r");
PyRun_SimpleFile(fp, "image.py");
fclose(fp);
// 导入Python模块
PyObject* pModule = PyImport_ImportModule("image");
// 获取Python函数对象
PyObject* pFunc = PyObject_GetAttrString(pModule, "resize_image");
// 设置Python函数参数
PyObject* pArgs = PyTuple_New(3);
PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", "test.jpg"));
PyTuple_SetItem(pArgs, 1, Py_BuildValue("s", "test_sm.jpg"));
PyTuple_SetItem(pArgs, 2, Py_BuildValue("(ii)", 128, 128));
// 调用Python函数
PyObject* pResult = PyObject_CallObject(pFunc, pArgs);
// 获取Python函数返回值
int result = (int) PyLong_AsLong(pResult);
printf("%d", result);
// 释放Python对象
Py_DECREF(pArgs);
Py_DECREF(pResult);
Py_DECREF(pFunc);
Py_DECREF(pModule);
// 关闭Python环境
Py_Finalize();
return 0;
}
上述代码中,我们调用resize_image函数将test.jpg压缩成128×128的尺寸,并保存为test_sm.jpg。函数的返回值是压缩后的文件大小(单位为字节)。