• 利用pybind11在python中使用C++


    1、pybind的安装

    1.1、安装依赖

    sudo apt-get install python-dev  (or python3-dev)
    sudo apt-get install cmake
    sudo pip install pytest
    sudo pip install numpy
    sudo pip install scipy
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.2、pip安装

     sudo pip install pybind11
    
    • 1

    1.3、源码安装

    • 1、创建目录
    • 2、获取pybind11源码包 https://github.com/pybind/pybind11
    • 3、下载Eigen http://eigen.tuxfamily.org/index.php?title=Main_Page
    • 4、在目录执行 mkdir build
    • 5 、cd build
    • 6、cmake ..
    • 7、make check -j 4
    • 8、 sudo make install

    1.4、使用brew 安装

    brew install pybind11
    
    • 1

    2、使用pybind进行C++代码编写


    这里以ROS为列,获取Baxter机器人上方的图片,为了简洁方便看,这里只放头文件和cmake文件


    2.1、头文件

    • rosBase.hpp
    #ifndef _ROS_H_
    #define _ROS_H_
    #include
    #include 
    #include
    #include
    class rosBase{
        public:
        rosBase(const std::string node_name,int argc=0,char**argv=nullptr);
    };
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • baxterImage.hpp
    #include
    #include
    #include
    #include
    #include 
    #include "opencv2/core/core.hpp"
    #include
    #include
    #include
    #include
    #include
    #include
    #include 
    static const std::string OPENCV_WINDOW = "Open-CV display window";
    #define headImage "/cameras/head_camera/image"
    #define leftImage "/cameras/left_hand_camera/image"
    #define rightImage "/cameras/right_hand_camera/image"
    
    class baxterImage:public rosBase{
        public:
        baxterImage(const std::string nodeName, std::string IP="*",int Port=5556,int rate=1000);
        void getImage(const std::string cameraName);
        void processImageCallBack(const sensor_msgs::ImageConstPtr& msg);
        bool baxterOk();
        void baxterSleep();
        void baxterRate(int rate);
        void baxterSpinOnce();
        private:
            ros::NodeHandle nh;
            ros::Subscriber headSub;
            ros::Subscriber leftSub;
            ros::Subscriber rigthSub;
            void *publisher=NULL;
            int rate;
            const std::string Port;
            const std::string IP;
            rosBase rosbase;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    2.2、下面是一个重要的文件 bindings.cpp

    用于把C++代码和python代码进行绑定

    #include
    #include
    #include
    #include
    namespace py = pybind11;
    PYBIND11_MODULE(baxter,m)
    {
        py::class_<rosBase>rosbase(m,"rosBase");
        rosbase.def(py::init<const std::string&>());
        py::class_<baxterImage>(m,"baxterImage",rosbase)
            .def(py::init<const std::string &,const std::string&,int ,int>())
            .def("getImage",&baxterImage::getImage)
            .def("baxterOk",&baxterImage::baxterOk)
            .def("baxterSleep",&baxterImage::baxterSleep)
            .def("baxterSpinOnce",&baxterImage::baxterSpinOnce)
            .def("baxterRate",&baxterImage::baxterRate);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    可以对着下面图像进行理解
    在这里插入图片描述

    2.3、Cmake文件

    cmake_minimum_required(VERSION 2.8.3)
    project(Ros_control)
    ## Compile as C++11, supported in ROS Kinetic and newer
    add_compile_options(-std=c++11)
    find_package(  OpenCV REQUIRED)
    find_package(Eigen3 REQUIRED)
    include_directories(
     include
      "/opt/ros/kinetic/include/"
      "/usr/include/"
      "/usr/include/boost/"
      "/usr/lib/python3.7/dist-packages/numpy/core/include/"
      "/usr/include/python3.7m/"
      "/headless/baxter_ws/devel/include/"
    )
    LINK_DIRECTORIES(
      "/opt/ros/kinetic/lib/"
      "/usr/lib/x86_64-linux-gnu/"
      "/opt/ros/kinetic/lib/x86_64-linux-gnu/"
      "/lib64/"
    )
    include_directories(SYSTEM ${EIGEN3_INCLUDE_DIRS})
    add_subdirectory(
      lib/pybind11
    )
    pybind11_add_module(baxter "src/rosBase.cpp" "src/baxterImage.cpp"  "src/bindings.cpp")
    target_link_libraries(
    baxter PRIVATE   ${OpenCV_LIBS}
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    可以把pybind11 的lib库拷入到编译目录的lib库中(不是必须,能找到对应的库就行)
    编译时会根据python版本生成baxter.cpython-37m-x86_64-linux-gnu.so文件

    3、使用

    把生成的so文件放到python文件使用的地方,或者让使用的文件能够找到此so文件

    3.1、使用的案例代码

    import baxter
    #push = baxter.baxterImage("pushimage","*",6666,1000)
    push = baxter.baxterImage("pushimage","192.168.1.105",6666,1000)
    push.getImage("h")
    while push.baxterOk():
        push.baxterSpinOnce()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    参考学习

  • 相关阅读:
    使用Kotlin优化Java开发
    博客项目(前后端分离)(servlet实战演练)
    C++征途 --- Vector容器
    [附源码]java毕业设计毕业生离校管理系统
    GaussDB CN服务异常实例分析
    【MFC】Button控件美化(自绘)
    laravel中锁以及事务的简单使用
    Apache-atlas-kafka-hook-源码分析
    【luogu P4590】游园会(DP套DP)
    如何对wps流程图进行重命名,如何对wps流程图进行重命名,wps进入修订模式,wps怎么在尾部加公式标号英文论文格式要求及字体大小
  • 原文地址:https://blog.csdn.net/u011573853/article/details/126027433