Python調(diào)用C++,通過Pybind11制作Python接口
我是在ubuntu系統(tǒng)進行實驗的,所以和window可能會有區(qū)別。
python調(diào)用C/C++有不少的方法,如boost.python, swig, ctypes, pybind11等,這些方法有繁有簡,而pybind11的優(yōu)點是對C++ 11支持很好,API比較簡單,現(xiàn)在我們就簡單記下Pybind11的入門操作。
1. pybind11簡介與環(huán)境安裝
pybind11是一個輕量級的只包含頭文件的庫,它主要是用來在已有的 C++代碼的基礎(chǔ)上做擴展,它的語法和目標非常像Boost.Python,但Boost.Python為了兼容現(xiàn)有的基本所有的C++編譯器而變得非常復雜和龐大,而因此付出的代價是很多晦澀的模板技巧以及很多不必要的對舊版編譯器的支持。Pybind11摒棄了這些支持,它只支持python2.7以上以及C++ 11以上的編譯器,使得它比Boost.Python更加簡潔高效。
為了使用pybind11,我們需要支持C++ 11標準的編譯器(GCC 4.8以上,VS 2015 Update 3以上)以及python 2.7以上的版本,還需要下載CMake,有了這些以后,
cmake教程可以參考://chabaoo.cn/article/148903.htm
- 首先,我們從 pybind11 github網(wǎng)址:https://github.com/pybind/pybind11 上下載源碼。
- cmake工程之前,要先安裝pytest pip install pytest,否則會出錯
- 用CMake編譯并運行測試用例:
進入pybind11的目錄, cd tests cmake .. cmake --build . --config Release --target check
如果所有測試用例都通過了,說明安裝成功了。
2. python調(diào)用C++
下載編譯好pybind11之后,我們就可以開始對著官方的pybind11 Tutorial進行學習了,詳細的入門教程及語法請參考官方文檔,這里,我們簡單演示下如何編寫供python調(diào)用的C++模塊.
首先,我們編寫一個C++源文件,命名為example.cpp
#include <pybind11/pybind11.h> namespace py = pybind11; int add(int i, int j) { return i + j; } PYBIND11_MODULE(example, m) { // optional module docstring m.doc() = "pybind11 example plugin"; // expose add function, and add keyword arguments and default arguments m.def("add", &add, "A function which adds two numbers", py::arg("i")=1, py::arg("j")=2); // exporting variables m.attr("the_answer") = 42; py::object world = py::cast("World"); m.attr("what") = world; }
2.1 使用window編譯
我沒有實驗,所以可以參考別的教程
2.2 CMake的編譯方法
當然,我們也可以使用CMake進行編譯。首先寫一個CMakeLists.txt
cmake_minimum_required(VERSION 2.8.12) project(example) add_subdirectory(pybind11) pybind11_add_module(example example.cpp)
這里要求example.cpp放在和pybind11同一級的目錄下,因為我們在CMakeLists.txt中調(diào)用了同目錄pybind11和同目錄的example.cpp文件。在當前目錄下執(zhí)行
cmake . make
會生成example.cpython-36m-x86_64-linux-gnu.so文件。這個文件就是python可以調(diào)用的文件。還是在相同目錄下運行python,進入python命令行
import example example.add(3, 4) [out]: 7
3、中級調(diào)用
上面是一個簡單的例子,有時我們需要的功能可能很復雜。
生成模型設(shè)計庫調(diào)用問題。
比如你的cpp文件中引用了其他的第三方庫,這個時候我們生成的so文件,可能是需要依賴第三方庫的。
本地myopencv.cpp文件
#include <pybind11/pybind11.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc.hpp> #include <string> namespace py = pybind11; void read_img(std::string img_path) { cv::Mat image = cv::imread(img_path, CV_LOAD_IMAGE_COLOR); } PYBIND11_MODULE(myopencv, m) { m.def("read_img", &read_img, "get image size"); }
CMakeLists.txt可以寫成下面這樣
cmake_minimum_required(VERSION 2.8.12) project(myopencv) add_subdirectory(pybind11) pybind11_add_module(myopencv myopencv.cpp)
通過cmkae編譯通過
cmake . make
產(chǎn)生myopencv.cpython-36m-x86_64-linux-gnu.so文件
在python中調(diào)用
import myopencv
目前這里發(fā)現(xiàn)有問題,還沒有調(diào)通
數(shù)據(jù)類型不匹配的問題
比如opencv在python中是numpy的類型,但是在c++中cv.Mat的類型
對于opencv的類型不匹配問題,github上已經(jīng)給出了解決方法,
cpp和h文件下載地址 https://github.com/edmBernard/pybind11_opencv_numpy
如何你需要什么可以去github上搜索,或者自己去實現(xiàn)。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接
相關(guān)文章
Python利用atexit模塊實現(xiàn)優(yōu)雅處理程序退出
Python的atexit模塊提供了一種方便的方式來注冊這些退出時執(zhí)行的函數(shù),文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下2024-03-03基于Python創(chuàng)建可定制的HTTP服務(wù)器
這篇文章主要為大家演示一下如何使用?http.server?模塊來實現(xiàn)一個能夠發(fā)布網(wǎng)頁的應(yīng)用服務(wù)器,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下2023-05-05Python Diagrams庫以代碼形式生成云系統(tǒng)架構(gòu)圖實例詳解
這篇文章主要介紹了Python Diagrams庫以代碼形式生成云系統(tǒng)架構(gòu)圖實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01深入理解Python?@dataclass的內(nèi)部原理
文章介紹了Python中dataclass的實現(xiàn)原理,通過自定義裝飾器實現(xiàn)了__init__和__repr__方法,并解釋了__annotations__屬性和exec函數(shù)在其中的作用,感興趣的朋友跟隨小編一起看看吧2025-01-01Pytorch可視化(顯示圖片)及格式轉(zhuǎn)換問題
這篇文章主要介紹了Pytorch可視化(顯示圖片)及格式轉(zhuǎn)換問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12