pybind11实现python、c++互调
当你想将Python和C++结合使用时,pybind11是一个强大的工具。它是一个轻量级的库,可以让你在C++中创建Python模块,方便地调用Python代码和使用Python库。使用pybind11,你可以简洁地编写接口代码,使C++和Python之间的交互变得简单和高效。同时,pybind11还提供了许多便利的功能,如自动类型转换、异常处理和线程支持。无论你是要在C++中调用现有的Python库,还是要将C++代码包装为Python模块,pybind11都能帮助你轻松实现。
代码项目下载地址:https://download.csdn.net/download/WangMiaoInters/88167827?spm=1001.2014.3001.5501
pybind11
pybind11官方文档:pybind11 doc
pybind11下载地址:github v2.11.1
下载好后进入库pybind11-2.11.1源码路径下,依次执行以下命令
(其实也可以解压后直接使用,不用执行什么)
mkdir build
cd build
cmake ..
cmake --build . --config Release #这里我是直接执行cmake --build .没有执行--config Release
make
在build -> tests下出现以下两个库即为成功
python调用c++
- 大致过程:使用cmake编译pybind11和c++程序后,会生成一个可供python调用的模块,python就是通过这个模块实现调用c++代码的;执行完cmake后会生成一个名为example_add.cpython-38-x86_64-linux-gnu.so的动态库,其中example_add就是模块名,在.py中通过import example_add即可调用c++。
- 需要注意的是,pybind11源码也要参与cmake中一起编译
- 目录结构
- pybind11下的CMakeLists.txt:
cmake_minimum_required(VERSION 3.4)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_subdirectory(third_part/pybind11-2.11.1) #必写
add_subdirectory(py_invoke_cpp)
add_subdirectory(cpp_invoke_py)
- py_invoke_cpp下的CMakeLists.txt:通过pybind11_add_module生成名为example_add的python模块
cmake_minimum_required(VERSION 3.4)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
project(example_add)
#不需要添加任何target,pybind11_add_module已经完成了所有事情
#pybind11_add_module在/work/miaow/pybind11/third_part/pybind11-2.11.1/tools/pybind11Tools.cmake里
pybind11_add_module(example_add example_add.cpp)
- example_add.cpp
#include <pybind11/pybind11.h>
namespace py = pybind11;
int add(int a, int b) {
return a + b;
}
//example_add需与文件名同名
PYBIND11_MODULE(example_add, m) {
m.def("add", &add, "A function which adds two numbers");
}
- .py文件:
import example_add
result = example_add.add(2, 3)
print("Result:", result)
- 运行:
把build下生成的example_add.cpython-38-x86_64-linux-gnu.so拷贝到.py文件同级目录执行
chmod +x example_add.py
python3 ./example_add.py
c++调用python
- 大致过程:使用pybind11,直接在.cpp里编写python代码,其余与普通c++代码没区别
- 目录:
- CMakeLists.txt
cmake_minimum_required(VERSION 3.4)
# 设置C++标准和优化级别
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
# 添加可执行文件
add_executable(cpp_invoke_py
main.cpp
)
include_directories(
/usr/include/python3.8
)
find_package(PythonLibs REQUIRED)
target_include_directories(cpp_invoke_py PRIVATE ${PYTHON_INCLUDE_DIRS})
target_link_libraries(cpp_invoke_py PRIVATE ${PYTHON_LIBRARIES})
其中,
${PYTHON_INCLUDE_DIRS}
值为:/usr/include/python3.8
${PYTHON_LIBRARIES}
值为:/usr/lib/x86_64-linux-gnu/libpython3.8.so
- main.cpp:
#include <iostream>
#include <pybind11/embed.h>
// #include <Python.h>
namespace py = pybind11;
int add(int a, int b) {
py::scoped_interpreter guard{}; // 初始化Python解释器
// 导入Python模块
py::module sys = py::module::import("sys");
py::module main = py::module::import("__main__");
py::object global = main.attr("__dict__");
// 执行Python代码
py::exec("def add(a, b):\n"
" return a + b", global);
// 调用Python函数
py::object result = global["add"](a, b);
// 将Python对象转换为C++类型
int sum = result.cast<int>();
return sum;
}
int main() {
int a = 2;
int b = 3;
int sum = add(a, b);
std::cout << "Sum: " << sum << std::endl;
return 0;
}
- 运行:直接运行build下的可执行文件