前言
C++和Python都是當前最流行的語言之一,其強大的功能毋庸置疑,它們分別在不同甚至相同的領域發揮着至關重要的作用。C++是底層開發中起着中流砥柱的作用,屹立多年依然勢頭強勁不露頹勢。而Python在最近大熱的數據挖掘和人工智能領域獨領風騷。而且Python爲數極其衆多的庫支持幾乎可以滿足各個領域的開發者的需求。
雖然他們都是非常強大的工具,但是在處理特定任務的時候,有時候會存在着方便與否的問題。比如說在算法實現上可能我更喜歡用C++,但是算法最後產生的數據卻想交給Python來處理,畢竟Python在數據處理方面用起來更加順手也更加簡單。本文中我們就來看一下如何把C++算法得到的數據vector<float>
交給Python然後用Excel畫出來。
環境配置
首先需要配置一下環境,我這裏用的分別是:
Visual Studio 2017
Anaconda 2 (64位)
正如在Visual Studio中配置其他庫(比如OpenCV
)一樣,我們需要在Visual Studio中添加三個東西
包含目錄
——include文件夾
庫目錄
——包含.lib文件的文件夾
附加依賴項
——.lib文件
按照上面的順序,我們需要分別將Python
安裝文件下的inlcude文件夾、libs
文件夾和libs文件夾下的python27.lib
添加到VS工程屬性的包含目錄、庫目錄和附加依賴項中去。如下圖:
這裏有兩點需要注意:
要把模式設置爲
Release
而不是Debug
,否則要把python27.lib
改名爲python27_d.lib
要根據安裝的Python的位數來選擇平臺爲數,比如這裏是64位
C++調用Python
在上代碼之前還是說一下C++調用Python的一些慣例比較好:
添加頭文件
Python.h
,確保文件夾include加入到了包含目錄才能調用成功調用的Python代碼都需要包含在兩行代碼中間,即如下形式:
Py_Initialize(); //首。初始化Python解釋器
//這裏是一堆其他代碼
Py_Initialize(); //尾。結束Python的工作。
跟Python相關的東西一般聲明爲PyObject指針的形式,比如一會見到的如下聲明:
PyObject * pModule = NULL; //Python模塊
PyObject * pFunc = NULL; //Python函數
PyObject * pArg = NULL; //函數接受的參數
用下面三行代碼來完成導入模塊、引入函數、構建參數的工作,都是”聞名如見面“類型的函數:
pModule = PyImport_ImportModule("test"); //導入模塊
pFunc = PyObject_GetAttrString(pModule, "write_to_xlsx"); //引入操作Excel的函數
pArg = Py_BuildValue("O,O", tuple1, tuple2); //把C++類型轉換爲Python類型
最後用一句,把參數傳給調用函數並實際運行:
PyEval_CallObject(pFunc, pArg);
實際上到這裏就已經把幾乎所有能用到的都說個差不多了,在具體說一下C++類型轉換爲Python類型之前,還是先看一下完整的代碼吧。
Show me your code.
vector轉爲tuple
其他的諸如引入模塊、函數之類的是沒啥難度的,只需要換個參數而已。這裏實際具有技術含量的就是vector對於轉化爲tuple這一部分了。
其中最主要的一個函數是PyObject *Py_BuildValue(char *format, ...);
,此函數作用就是把後面的參數轉換成第一個參數format
指定的形式,最終返回一個Python對象。官方給出的例子有這些:
但是當我想要把兩個vector傳給轉換成兩個tuple的時候,上面給出的N種形式都顯得力不從心了。我們希望兩個vector傳遞給Python的時候轉換成了兩個tuple。但是最後的結果經常是變成了一個個的單個元素,就是不能把這些元素按照原來的vector分成兩個元組。經過苦讀文檔加上實驗,format參數是'O'的時候能夠滿足需求。但是需要我們先把vector轉成tuple才能格式化參數。
PyObject* tuple = PyTuple_New(data.size());
先通過PyTuple_New
創建一個Python對象,然後利用PyTuple_SET_ITEM
把vector的元素一個一個添加到tuple
裏面去:
PyTuple_SET_ITEM(tuple, i, Py_BuildValue("f", data[i]));
這樣,參數就可以經過Py_BuildValue
格式化之後傳給被調用的函數了。
調用的Python程序
在本文中被調用的Python程序不是我們關注的重點,所以Python代碼直接放在這裏不做過多的解釋。大概意思就是利用Openpyxl
,把接收的數據寫入Excel,然後畫出柱狀圖。也許以後會放出這方面的內容。現在就只是知道調用的代碼長什麼樣就行。以下是test.py
的內容:
最後的效果
可以看到,傳遞給Python的參數已經成功的寫入Excel並畫出了直方圖。值得注意的一點是,VS運行程序的時候Excel要關閉,不然會發生寫入數據失敗。