基于ubuntu 16.04系统,使用python3调用c++生成的动态链接库
1. pybind11的两种方式:
1)使用pip安装
pip install pybind11 -i https://pypi.tuna.tsinghua.edu.cn/simple/
2)源码编译(推荐这种,方便后续CmakeLists.txt中使用find_package(pybind11 REQUIRED))
pip install pytest -i https://pypi.tuna.tsinghua.edu.cn/simple/
git clone https://github.com/pybind/pybind11.git
cd pybind11
mkdir build
cd build
cmake ..
make -j4
sudo make install
2. 使用CMakeLists.txt生成动态链接库so
1)使用的源文件为:map_interface.cpp
#include "map_interface.h"
#include <iostream>
int MapInterface::CreateObj(int img_row, int img_col){
return img_col*img_row;
}
void MapInterface::SetCameraParas(int para){
std::cout << "para: " << para << std::endl;
}
bool MapInterface::AddImgFeatures(int frame_index){
std::cout << "frame_index: " << frame_index << std::endl;
return true;
}
bool MapInterface::AddImgFeatures2(int frame_index){
std::cout << "AddImgFeatures2: " << frame_index << std::endl;
return true;
}
void MapInterface::DestroyObj(){
std::cout << "-------DestroyObj------" << std::endl;
}
2)对应的头文件为:map_interface.h
#include <pybind11/pybind11.h>
namespace py = pybind11;
class MapInterface
{
public:
int CreateObj(int img_row, int img_col);
void SetCameraParas(int para);
bool AddImgFeatures(int frame_index);
// 为了便于pybind11 调用,这里暂时不使用重载函数功能
bool AddImgFeatures2(int frame_index);
void DestroyObj();
};
PYBIND11_MODULE(libmap_interface, m) {
m.doc() = "pybind11 Hierarchical Localization cpp backend";
py::class_<MapInterface>(m, "MapInterface")
.def(py::init())
.def("CreateObj", &MapInterface::CreateObj, py::return_value_policy::copy)
.def("SetCameraParas", &MapInterface::SetCameraParas)
.def("AddImgFeatures", &MapInterface::AddImgFeatures, py::return_value_policy::copy)
.def("AddImgFeatures2", &MapInterface::AddImgFeatures2, py::return_value_policy::copy)
.def("DestroyObj", &MapInterface::DestroyObj);
};
3)CMakeLists.txt文件为:
cmake_minimum_required(VERSION 3.18.2)
project(HFnet_map)
add_compile_options(-std=c++11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -g")
set(CMAKE_BUILD_TYPE "Release")
set(PYBIND11_CPP_STANDARD -std=c++11)
find_package(pybind11 REQUIRED)
INCLUDE_DIRECTORIES(
${pybind11_INCLUDE_DIRS}
./
)
add_library(map_interface MODULE
map_interface.cpp
)
target_link_libraries(map_interface
pybind11::module
)
注意点:
在使用过程中, 有三个地方的变量命名需要一致,分别是上述代码中的: PYBIND11_MODULE接口函数中的map_interface, CMakeList中的add_library中的map_interface, python代码中的 import map_interface. 如下:
1、PYBIND11_MODULE(map_interface, m)
2、add_library(map_interface MODULE … )
3、import map_interface # c++接口
这里,全部统一定义成map_interface. 否则在python调用时会出现如下等错误:
ModuleNotFoundError: No module named XXXXXX
在运行python程序时,还会出现错误:
ImportError: dynamic module does not define module export function (PyInit_libxxxx)
这个问题仍然是这三个地方的命名不一致导致的,需要注意的是, linux 系统在使用 CMake 编译 c++ 动态链接库的时候, 会加一个前缀lib, 生成libmap_interface.so, 因此,这三个地方的命名应该修改如下:
1、PYBIND11_MODULE(libmap_interface, m)
2、add_library(map_interface MODULE … )
3、import libmap_interface # c++接
参考自:https://blog.csdn.net/zouzoupaopao229/article/details/106802249