windows10系统下基于pybind11库进行c++代码调用python(pytorch)代码

Posted s182838ss

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了windows10系统下基于pybind11库进行c++代码调用python(pytorch)代码相关的知识,希望对你有一定的参考价值。

最近在学习基于lidar-mos进行slam激光点云动态物体剔除的相关内容,经过调研准备基于pybind11库在实际项目(c++)中调用salsaNext代码(python)。

  1. 使用cmake在测试项目中引入pybind11库,CMakeLists.txt文件内容为:

cmake_minimum_required(VERSION 3.15)

project(test LANGUAGES CXX)

find_package(pybind11 CONFIG REQUIRED)

add_executable(convert main.cpp)

target_link_libraries(convert PRIVATE pybind11::embed pybind11::module)

pybind11库有多种安装方式,我是在vcpkg里安装管理的。

  1. 在程序运行目录下,拷贝python相关文件和文件夹:

其中DLLS、Lib和python39.dll为对应python环境的依赖项,LiDAR-MOS为准备调用的python代码。libiomp5md.dll和uv.dll后面会提到为啥需要。

  1. pybind11是一个头文件库,包含必要的头文件后就可以进行python解释器的初始化,然后就可以在c++中调用lidar-mos的python代码了。

#include <pybind11/embed.h>
#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
#include <pybind11/stl.h>
#include <iostream>

namespace py = pybind11;

int main()

    py::scoped_interpreter guard;//python解释器的初始化
    // py::print("Hello, World!");

    py::module sys = py::module::import("sys");
    sys.attr("path").attr("append")("D:\\\\workSpace2022\\\\project_vs\\\\dynamic_removeTest\\\\build\\\\Release\\\\DLLs");
    sys.attr("path").attr("append")("D:\\\\workSpace2022\\\\project_vs\\\\dynamic_removeTest\\\\build\\\\Release\\\\Lib");
    sys.attr("path").attr("append")("D:\\\\workSpace2022\\\\project_vs\\\\dynamic_removeTest\\\\build\\\\Release\\\\Lib\\\\site-packages");
    sys.attr("path").attr("append")("D:\\\\workSpace2022\\\\project_vs\\\\dynamic_removeTest\\\\build\\\\Release\\\\LiDAR-MOS\\\\utils\\\\");
    //sys.attr("path").attr("append")("D:\\\\workSpace2022\\\\project_vs\\\\dynamic_removeTest\\\\build\\\\Release\\\\LiDAR-MOS\\\\utils\\\\auxiliary");
    sys.attr("path").attr("append")("D:\\\\workSpace2022\\\\project_vs\\\\dynamic_removeTest\\\\build\\\\Release\\\\LiDAR-MOS\\\\mos_SalsaNext");
    sys.attr("path").attr("append")("D:\\\\workSpace2022\\\\project_vs\\\\dynamic_removeTest\\\\build\\\\Release\\\\LiDAR-MOS\\\\mos_SalsaNext\\\\train");
    sys.attr("path").attr("append")("D:\\\\workSpace2022\\\\project_vs\\\\dynamic_removeTest\\\\build\\\\Release\\\\LiDAR-MOS\\\\mos_SalsaNext\\\\train\\\\tasks\\\\semantic");
    sys.attr("path").attr("append")("D:\\\\workSpace2022\\\\project_vs\\\\dynamic_removeTest\\\\build\\\\Release\\\\LiDAR-MOS\\\\mos_SalsaNext\\\\train\\\\tasks\\\\semantic\\\\dataset\\\\kitti");

    //py::print(sys.attr("path"));

    py::module os = py::module::import("os");
    //py::print(os.attr("getcwd")());

    py::module yaml = py::module::import("yaml");
    
    /*try 
        py::module matplotlib = py::module::import("matplotlib");
    
    catch (py::error_already_set& e) 
        py::print(e.type());
        py::print(e.what());

    */

    try 
        py::module torch = py::module::import("PIL");
    
    catch (py::error_already_set& e) 
        py::print(e.type());
        py::print(e.what());

    
    
    py::object chdir = os.attr("chdir");
    //chdir("D:\\\\workSpace2022\\\\project_vs\\\\dynamic_removeTest\\\\build\\\\Release\\\\LiDAR-MOS\\\\mos_SalsaNext\\\\train\\\\tasks\\\\semantic");
    chdir("D:\\\\workSpace2022\\\\project_vs\\\\dynamic_removeTest\\\\build\\\\Release\\\\LiDAR-MOS");
    //py::print(os.attr("getcwd")());


    /*auto module = py::module::import("calc22");
    int n = module.attr("add")(1, 2).cast<int>();*/

    /*auto module = py::module::import("gen_residual_images");
    module.attr("gen_resiImages")();*/

    
    /*auto moduleInfer = py::module::import("infer");
    moduleInfer.attr("doSomethingInfer")("../../../../data", "../../../../data/predictions_salsanext_residual_1_new"
        , "../../../../data/model_salsanext_residual_1",false, 30,"valid");*/

    /*auto moduleEva = py::module::import("evaluate_mos");
    moduleEva.attr("doEvaluate_mos")();*/

    auto moduleVisualize = py::module::import("visualize_mos");
    moduleVisualize.attr("visualizeMos")("data", "data/predictions_salsanext_residual_1_valid", 8);

    return 0;

pybind11的语法是比较简单,容易上手的。py::module::import导入模块(python文件),module.attr("method")调用方法和属性。

在这之前,先使用sys.path.append加上对应python文件的路径,否则会导入模块失败。

  1. 遇到的问题,重点记录。

4.1 matplotlib模块导入错误,在python环境下没问题

脱离python环境下,c++代码调用就出如下错误

但是明明有matplotlib文件夹,就很奇怪。解决办法:还好这模块并没有实际使用,先注释了事。

4.2 导入torch模块时,提示shm.dll错误

这种一般是缺少对应的dll或者依赖dll,借助Dependencies工具,查看shm.dll缺少哪些依赖项。

一查都不缺,当时头都大了,后来发现是torch_cpu.dll缺少依赖。如下图中红色的两个。

解决办法:在对应的完整python环境下搜索对应的dll,复制到Release下,解决。

c++应用程序convert.exe成功调用pytroch模型进行训练数据

以上是关于windows10系统下基于pybind11库进行c++代码调用python(pytorch)代码的主要内容,如果未能解决你的问题,请参考以下文章

基于pybind11实现Python调用c++编写的CV算法--下 (Linux+Cmake)

使用pybind11开发python扩展库(10)

pybind11在Windows下的使用

在 Windows 上使用第三方 C++ 进行 pybind (ImportError: DLL load failed)

基于DJango和Pybind11,实现网络后端调用OpenCV算法

基于DJango和Pybind11,实现网络后端调用OpenCV算法