首先通过Python C API在C++中初始化解释器并执行脚本,接着导入模块调用具体函数如add(a, b),传参并获取返回值,最后清理资源;需链接Python库编译。

在C++项目中调用Python脚本,通常是为了利用Python丰富的库生态(如NumPy、Pandas、机器学习框架等),同时保留C++在性能和系统级编程上的优势。实现C++与Python交互的核心方式是使用Python官方提供的C API。下面详细介绍如何在C++中调用Python脚本,并给出实用示例。
1. 使用Python C API直接调用脚本
Python自带的C API允许C/C++程序嵌入Python解释器,从而执行Python代码或调用脚本文件。
基本步骤:
- 初始化Python解释器(Py_Initialize)
- 执行Python脚本(PyRun_SimpleString 或 PyRun_File)
- 调用Python函数(通过 PyObject 获取模块和函数)
- 清理资源(Py_Finalize)
示例代码:
立即学习“Python免费学习笔记(深入)”;
#include#include int main() { // 初始化Python解释器 Py_Initialize();
if (!Py_IsInitialized()) { std::cerr << "Failed to initialize Python" << std::endl; return -1; } // 执行一个简单的Python语句 PyRun_SimpleString("print('Hello from Python!')"); // 执行外部.py文件 FILE* fp = fopen("test.py", "r"); if (fp) { PyRun_SimpleFile(fp, "test.py"); fclose(fp); } else { std::cerr << "Cannot open Python script" << std::endl; } // 清理 Py_Finalize(); return 0;}
注意:编译时需要链接Python库。例如Linux下使用g++:
g++ -o call_python call_python.cpp -I/usr/include/python3.x -lpython3.x
2. 调用Python函数并传递参数
更高级的用法是从C++调用Python模块中的具体函数,并传入参数、获取返回值。
示例:调用 test.py 中的 add(a, b) 函数
PyObject* pModule = PyImport_ImportModule("test"); // 导入模块
if (!pModule) {
PyErr_Print();
std::cerr << "Failed to load module" << std::endl;
return -1;
}
PyObject* pFunc = PyObject_GetAttrString(pModule, "add"); // 获取函数
if (!pFunc || !PyCallable_Check(pFunc)) {
std::cerr << "Function not found or not callable" << std::endl;
return -1;
}
// 构造参数元组
PyObject* pArgs = PyTuple_New(2);
PyTuple_SetItem(pArgs, 0, PyLong_FromLong(5));
PyTuple_SetItem(pArgs, 1, PyLong_FromLong(3));
// 调用函数
PyObject* pResult = PyObject_CallObject(pFunc, pArgs);
if (pResult) {
long result = PyLong_AsLong(pResult);
std::cout << "Result: " << result << std::endl;
} else {
PyErr_Print();
}
// 释放对象
Py_DECREF(pArgs);
Py_DECREF(pFunc);
Py_DECREF(pModule);
Py_XDECREF(pResult);
对应的 test.py 文件内容:
def add(a, b):
return a + b
3. 处理异常与类型转换
C++调用Python容易出错,必须检查每一步的返回值。
- 使用 PyErr_Occurred() 检查是否有异常
- 使用 PyFloat_AsDouble、PyUnicode_AsUTF8 等安全转换返回值
- 所有创建的 PyObject* 都需正确减少引用计数(Py_DECREF)防止内存泄漏
例如获取字符串返回值:
PyObject* pResult = PyObject_CallObject(pFunc, pArgs);
if (pResult) {
const char* str = PyUnicode_AsUTF8(pResult);
std::cout << "String result: " << str << std::endl;
}
4. 第三方工具简化交互
原生C API较为繁琐,可使用以下库提升开发效率:
- pybind11:现代C++绑定工具,支持双向调用,语法简洁
- Boost.Python:功能强大但依赖Boost,编译较重
- SWIG:适用于大型项目接口生成
推荐使用 pybind11,它能让你像写普通C++函数一样暴露接口给Python,也支持从C++中导入Python对象。
基本上就这些。掌握Python C API后,可以在高性能C++程序中灵活集成Python脚本,实现功能扩展。关键是初始化、调用、异常处理和资源释放四个环节不能出错。环境配置和头文件路径要准确,版本要匹配(如Python 3.8对应 python3.8-dev 包)。











