2017-04-13 64 views
2

我有一個主文件(main.cpp)和一個頭文件(nodes.hpp)。主文件以N(任何正整數)作爲輸入參數,並使用頭文件的函數給出輸出說'x & y'(都是double)。用Python包裝C++代碼(手動)

注:

  1. 兩個主要和頭文件用C++編寫。
  2. 主文件和頭文件都不使用數據結構作爲數組,向量,而是使用特徵庫。

我必須爲他們編寫一個python包裝,我有python的工作知識,但從未使用過任何包裝。

任何人都可以請參考或提供一些關於使用python wrpper這樣的代碼的筆記嗎?

+0

也許從[閱讀文檔]開始(https:// docs。python.org/3/extending/index.html),其中還提到了一些您可以調查的第三方工具。 – Useless

+0

最好的和最現代的庫之一是[pybind11](https://github.com/pybind/pybind11)(它每天越來越流行)。沒有太多的經驗,這除了cython是我嘗試過的唯一一個,它運行得非常好。 Boost.Python通常被認爲很好用,相比之下像SWIG和co。但它受到boost的構建工具的限制。這就是pybind11如果能夠使用現代C++編譯器的話就會被拋棄的! – sascha

回答

5

使用Boost.Python。這是我的教程,以前在SO Docs上。


使用Boost.Python的

事情是容易當你有一個Python項目中使用C++庫。你可以使用Boost。

的一切都在這裏首先是你所需要的組件列表:

  • 一個CMakeList.txt文件,因爲你要使用CMake的。
  • C++項目的C++文件。
  • python文件 - 這是你的python項目。

讓我們從一個小的C++文件開始。我們的C++項目只有一個方法返回一些字符串「這是第一次嘗試」。說它CppProject.cpp

char const *firstMethod() { 
    return "This is the first try."; 
} 

BOOST_PYTHON_MODULE(CppProject) { 
    boost::python::def("getTryString", firstMethod); // boost::python is the namespace 
} 

有一個CMakeLists。txt文件如下:

cmake_minimum_required(VERSION 2.8.3) 
FIND_PACKAGE(PythonInterp) 
FIND_PACKAGE(PythonLibs) 
FIND_PACKAGE(Boost COMPONENTS python) 

INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}) 

PYTHON_ADD_MODULE(NativeLib CppProject) 
FILE(COPY MyProject.py DESTINATION .) # See the whole tutorial to understand this line 

通過本教程的這一部分,一切都非常簡單。你可以在你的python項目中導入庫和調用方法。打電話給你的python項目MyProject.py

import NativeLib 
print (NativeLib.getTryString) 

爲了運行項目按照以下說明:

  • 名爲構建創建一個目錄。
  • 進入該目錄。
  • 發出命令cmake -DCMAKE_BUILD_TYPE=Release ..
  • make
  • python MyProject.py。現在,你必須看到你的C++項目中的方法返回的字符串。
1

這裏是你的選擇:

  1. 您可以使用ctypes,並且我認爲這是最乾淨的解決方案,因爲你轉換你的程序到共享庫,可以通過任何其他軟件來調用,而不是隻有Python。但是,您必須自己爲您的程序編寫一個C接口。

  2. 您可以使用Python C-Extension,我認爲這是最糟糕的解決方案,因爲它的級別非常低,容易發生內存泄漏,並且需要花費大量時間來實現一個函數,並且依賴於Python版本。基本上這是在你的C++中啓動一個Python解釋器的好處。您可以創建PyObjects(這是任何Python類型的主要構建模塊),並處理它們的insdie C/C++。

  3. 您可以使用SWIG,它會自動創建必須通過您定義的接口文件與ctypes創建的接口。人們說它非常好,但文檔不太好。

  4. 你可以使用Boost.Python,這很好,但它有一個非常醜陋的構建系統與bjam。如果你可以設法繞過,那麼它甚至比ctypes更好。我是一個很大的推動者,但是bjam是我不使用它的原因。

我通常做的是ctypes。我相信它,因爲它強調single-reponsibility principle。該庫有一個與接口(C接口)分開的作業,它也與使用該接口的Python腳本分離,並向用戶公開「簡單功能」。

0

C++包裝生成的另一個工具是CLIF。 2017年發佈的Google最近使用了這個功能。我們不再允許在內部爲Python編寫新的SWIG包裝。

它是建立在C++的語法分析鏘的頂部,並需要相對地道的現代C++ API使用(不出所料以下Google's Style Guide),而不是任何試圖讓你拍攝自己通過SWIG的腳「支持一切不好」的做法。