python調用C++

安裝pybind11

爲了使用C++ 編寫python的擴展程序,參見[1],這裏要介紹的是使用pybind11[3], pybind11使用比較簡單,文檔也比較詳細。

本人的開發/測試環境爲:

  • Ubuntu 18.04
  • pybind11
  • Anaconda3, with python 3.6
  • cmake

pybind11下載https://github.com/pybind/pybind11

下載好後,進入該目錄進行安裝:

mkdir build
cd build
cmake ..
make check -j 4

最後目錄裏的文件如下:

cpp+python

簡單的例子: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");
}

編譯:

c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` example.cpp -o example`python3-config --extension-suffix`

 會生成一個.so文件 example.cpython-36m-x86_64-linux-gnu.so

添加python環境變量:當前.so文件所在路徑,這樣python就能使用這個模塊了

export PYTHONPATH=$PYTHONPATH:/home/lzhr/workspace/libface

運行:

接下來,將其改成參數支持numpy,可參考官網文檔pybind11—python numpy與C++數據傳遞

#include<iostream>
#include<pybind11/pybind11.h>
#include<pybind11/numpy.h>

namespace py = pybind11;

/*
1d矩陣相加
*/
py::array_t<double> add_arrays_1d(py::array_t<double>& input1, py::array_t<double>& input2) {

    // 獲取input1, input2的信息
    py::buffer_info buf1 = input1.request();
    py::buffer_info buf2 = input2.request();

    if (buf1.ndim !=1 || buf2.ndim !=1)
    {
        throw std::runtime_error("Number of dimensions must be one");
    }

    if (buf1.size !=buf2.size)
    {
        throw std::runtime_error("Input shape must match");
    }

    //申請空間
    auto result = py::array_t<double>(buf1.size);
    py::buffer_info buf3 = result.request();

    //獲取numpy.ndarray 數據指針
    double* ptr1 = (double*)buf1.ptr;
    double* ptr2 = (double*)buf2.ptr;
    double* ptr3 = (double*)buf3.ptr;

    //指針訪問numpy.ndarray
    for (int i = 0; i < buf1.shape[0]; i++)
    {
        ptr3[i] = ptr1[i] + ptr2[i];
    }

    return result;

}


PYBIND11_MODULE(example, m) {
    m.doc() = "Simple demo using numpy!";
    m.def("add_arrays_1d", &add_arrays_1d);
}

執行同樣的編譯命令,然後python測試:

cmake編譯pybind11

如果是用CMake編譯的話,pybind11文件夾拷貝到/home/lzhr/workspace/libface/pydemo目錄下,和example.cpp代碼同級。

CMakeLists.txt如下:

cmake_minimum_required(VERSION 2.8.12)
project(example)

add_subdirectory(pybind11)
pybind11_add_module(example example.cpp)

執行命令:

cmake .
make

編譯成功後,添加下PYTHONPATH,就可以調用了

 

 

 

【參考】

[1] 如何實現 C/C++ 與 Python 的通信?

https://www.zhihu.com/question/23003213

[2] python 調用c++處理數組和圖片

https://blog.csdn.net/koibiki/article/details/89478458

[3] pybind11官網介紹

https://pybind11.readthedocs.io/en/stable/basics.html

[4] pybind11—opencv圖像處理(numpy數據交換)

https://www.jianshu.com/p/be16847b0b74

[5] pybind11—目標跟蹤demo(深度學習人臉檢測跟蹤)

https://www.jianshu.com/p/5dc844002d72

[6] 混合編程[python+cpp+cuda]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章