Python与c++互相调用(pybind11)
1.安装pybind11
看网上使用pip install pybind11,没有弄明白,因此下载源码编译。
1.1 下载pybind11
git clone https://github.com/pybind/pybind11.git
1.2 源码编译
cd /pybind11
mkdir build
cd build
cmake ..
make
编译完成
2. cpp样例
//example.cpp
#include <pybind11/pybind11.h>
#include "Abstract.h"
namespace py = pybind11;
int add(int i, int j) {
return i + j;
}
int sub(int i, int j) {
return i *j;
}
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin"; // optional module docstring
m.def("add", &add, "A function which adds two numbers");
m.def("sub", &sub, "A function which subtracts two numbers");
py::class_<DataParser>(m, "DataParser")
.def(py::init<const char*>())
.def("mkdir_savefold", &DataParser::mkdir_savefold)
.def("work", &DataParser::work);
}
创建add和sub两个函数,调用Abstruct.h中定义的DataParser类,具体实现在Abstruct.cpp中,DataParser有两个方法mkdir_savefold()和work()需要供Python调用。DataParser构造函数需要传入一个文件路径,使用const char*的类型。
3. CMAKE编译
CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(example)
set(CMAKE_CXX_STANDARD 17)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=gnu++0x")
add_subdirectory(pybind11) # 添加一个子目录并构建该子目录 ,子目录下应该包含cmakelist.txt和代码文件
pybind11_add_module(example example.cpp Abstract.cpp)
target_link_libraries(example PRIVATE
/usr/lib/x86_64-linux-gnu/libtiff.so
gdal
/usr/lib/x86_64-linux-gnu/libgflags.so)
PRIVATE 动态链接
mkdir build
cd build
cmake ..
make
我是在linux下编译的,编译完成后
会有一个很长的.so文件。
4. Python调用
新建一个py文件
将so文件放到py文件同目录下
import example
result_1 = example.add(3,4)
print(result_1)
result_2 = example.sub(3,4)
print (result_2)
parser = example.DataParser("/result_data/")
parser.mkdir_savefold()
parser.work()
结果
5 cpp调用python
pybind11编译与之前一致
5.1 python准备
def process(tiff_1, tiff_2):
time1 = time.time()
# img1 = cv2.imread('b1.tiff')
img1 = cv2.imread(tiff_1)
m1, n1, num1 = img1.shape
# img2 = cv2.imread('b3.tiff')
img2 = cv2.imread(tiff_2)
img0 = None
函数无返回值,作为示例。
5.2 cpp准备
#include <pybind11/embed.h> // 使用 pybind11 嵌入 Python
#include <iostream>
namespace py = pybind11;
int main() {
// 初始化 Python 解释器
py::scoped_interpreter guard{};
try {
// 导入 Python 模块
py::object process_module = py::module_::import("work");
// 获取 Python 函数
py::object process_function = process_module.attr("process");
// 调用 Python 函数并获取结果
process_function("/work/pybindtest/p2cso/b1.tiff", "/work/pybindtest/p2cso/b3.tiff");
} catch (const std::exception &e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
5.3 CMakeLists.txt准备
cmake_minimum_required(VERSION 3.20)
project(EmbedPythonExample)
set(CMAKE_CXX_STANDARD 11)
add_subdirectory(pybind11)
# find_package(pybind11 REQUIRED) # 查找 pybind11 包
add_executable(python_embed main.cpp) # 生成可执行文件
target_link_libraries(python_embed PRIVATE pybind11::embed) # 链接 pybind11
编译执行,OK!!!
作者:欢迎下辈子光临