使用Pybind11把C++代码编译成动态库so,支持Python的调用

基于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

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值