C++:c++中调用Python代码的几种方法
2025-01-29
- 使用 Python C API
- 通过
system()
函数调用 Python 脚本 - 嵌入 Python 解释器
- 使用第三方库,如
pybind11
或Boost.Python
建议使用第四种的示例二,比较简单,有其他博客讲解visual studio怎么配置环境。
1. 使用 Python C API
Python 提供了一个 C API,允许在 C/C++ 程序中嵌入 Python 代码。首先需要确保 Python 开发包已经安装。你可以通过 #include <Python.h>
来使用 Python C API。
示例:
#include <Python.h>
int main() {
// 初始化 Python 解释器
Py_Initialize();
// 运行简单的 Python 代码
PyRun_SimpleString("print('Hello from Python in C++!')");
// 关闭 Python 解释器
Py_Finalize();
return 0;
}
编译时,需要链接 Python 库:
g++ my_program.cpp -o my_program -I/usr/include/python3.x -lpython3.x
2. 通过 system()
函数调用 Python 脚本
你可以使用 C++ 的 system()
函数来调用外部 Python 脚本。虽然简单,但这方法不太灵活。
示例:
#include <cstdlib>
int main() {
// 通过系统命令调用 Python 脚本
system("python3 my_script.py");
return 0;
}
3. 嵌入 Python 解释器
嵌入 Python 解释器允许你更灵活地调用 Python 函数和模块。你可以使用 Python C API 调用 Python 函数、传递参数、获取返回值等。
示例:
#include <Python.h>
int main() {
Py_Initialize(); // 初始化 Python 解释器
// 导入 Python 模块
PyObject* pModule = PyImport_ImportModule("math");
if (pModule != nullptr) {
// 获取模块中的函数
PyObject* pFunc = PyObject_GetAttrString(pModule, "sqrt");
if (pFunc && PyCallable_Check(pFunc)) {
// 准备调用参数
PyObject* pArgs = PyTuple_Pack(1, PyFloat_FromDouble(9.0));
// 调用 Python 函数
PyObject* pValue = PyObject_CallObject(pFunc, pArgs);
if (pValue != nullptr) {
double result = PyFloat_AsDouble(pValue);
std::cout << "Result of sqrt(9.0) = " << result << std::endl;
Py_DECREF(pValue);
}
Py_DECREF(pArgs);
Py_DECREF(pFunc);
}
Py_DECREF(pModule);
}
Py_Finalize(); // 关闭 Python 解释器
return 0;
}
4. 使用 pybind11
pybind11
是一个用于 C++ 和 Python 交互的库,可以轻松地将 Python 代码嵌入 C++,并允许你在 Python 中使用 C++ 代码。
安装 pybind11
:
pip install pybind11
示例1:
#include <pybind11/embed.h> // 需要包含此头文件
namespace py = pybind11;
int main() {
py::scoped_interpreter guard{}; // 启动 Python 解释器
py::exec(R"(
print("Hello from Python inside C++ using pybind11!")
)");
return 0;
}
示例2:
Python 脚本:假设你的 Python 文件 my_script.py
里有一个函数 greet
,你想从 C++ 传递一个字符串参数给它,并让它执行。
# my_script.py
def greet(name):
print(f"Hello, {name}!")
C++ 代码:使用 pybind11
来加载这个 Python 文件,调用 greet
函数并传递参数。
#include <pybind11/embed.h>
#include <iostream>
#include <string>
namespace py = pybind11;
int main() {
py::scoped_interpreter guard{}; // 初始化 Python 解释器
try {
// 导入 Python 脚本
py::object my_script = py::module_::import("my_script");
// 从 Python 脚本中获取函数
py::object greet_func = my_script.attr("greet");
// 调用函数并传递 C++ 字符串
std::string name = "ChatGPT";
greet_func(name);
} catch (const std::exception &e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
编译并运行:
- 你需要将 Python 包路径包括在编译中,并链接 Python 库。
- 例如,使用
g++
编译:
g++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` my_program.cpp -o my_program `python3-config --ldflags`
关键步骤说明:
py::module_::import("my_script")
:加载 Python 文件my_script.py
(注意,该文件应该在执行的路径下或 Python 可查找的路径下)。my_script.attr("greet")
:获取 Python 中定义的greet
函数。greet_func(name)
:调用函数并传递std::string
参数。
运行时注意:
确保 Python 的文件(my_script.py
)和编译的 C++ 程序位于同一目录,或者将 Python 文件的路径添加到 Python 的模块搜索路径中。
示例输出:
Hello, ChatGPT!