美文网首页
学习pybind11(2):Hello World例子

学习pybind11(2):Hello World例子

作者: BetterCV | 来源:发表于2019-12-01 21:26 被阅读0次

    首先要明白pybind11是干啥的,对于一个C/C++库,可以用pybind11封装它的接口为Python接口,这样得到一个python库,就可以把功能强大的库丢给使用python的boys & girls使用了~

    因此,使用pybind11做封装,是我们“library developer”干的事情,说不上底层,但也比较底层了。你应该会用CMake,你也应该熟悉C/C++和Python。你编译出来的python库,其实就是一个.so结尾的动态库,也就是python里的一个module。

    现在实现一个add(a, b)的接口,功能是计算两个数字的和。不考虑各种边界情况。

    开工:

    mkdir -p ~/work/test/toy
    cd $_
    mkdir 3rdparty
    git clone https://github.com/pybind/pybind11 3rdparty/pybind11
    mkdir build
    mkdir src
    touch src/example.cpp
    touch CMakeLists.txt
    

    目录结构:


    image.png

    src/example.cpp

    #include <pybind11/pybind11.h>
    
    int add(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");
    }
    

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.14)
    
    project(toy)
    
    set(CMAKE_CXX_STANDARD 11)
    
    add_subdirectory(3rdparty/pybind11)
    pybind11_add_module(example src/example.cpp)
    

    执行构建:

    cd build
    cmake ..
    make
    
    image.png

    其中红框里的.so文件就是我们生成的python库了。在python中加载它(盘它!):

    python
    import example
    example.add(100, 200)
    
    example.__doc__
    
    image.png

    简要分析说明

    这里的CMakeLists.txt中,通过加载pybind11目录,会把pybind11/tools/pybind11Tools.cmake中的pybind11_add_module()函数引入。这个函数的功能,是创建一个指定名字的库(target是一个动态库);但是,会修改库文件名字的前缀后缀;并且还有一堆其他的编译链接设定。因此这里不通过手动add_library()命令来创建target,而是先包含pybind11目录再用pybind11_add_module()函数。

    也就是说,pybind11被当成一个3rdparty库被引入当前工程。从代码版本控制的角度看,可以把它弄成一个submodule,当然如果强项作为源码管理也可以,但是要注意tests子目录有3M大,可以考虑删除。

    C/C++代码中的exampleCMakeLists.txt中的target名字,要保持一致吗?

    是的,要保持一致。譬如把C++中的example改为exampleMod则虽然能编译出库,但是Python中无法import:

    image.png

    相关文章

      网友评论

          本文标题:学习pybind11(2):Hello World例子

          本文链接:https://www.haomeiwen.com/subject/dastgctx.html