C++調用python代碼

【需求】:使用c++調用python中sklearn包的SVM,訓練+識別。
【需要解決的問題】:相關的環境配置,c++與python數據類型的互轉,不安裝python的環境下運行。

【測試用的python包】:python2.7.14-32位
【測試用的vs工程】:debug 32位

【步驟】:(具體的示例,在這裏
1. 先配置VS的項目屬性,一個是包含目錄,一個是庫目錄。
包含目錄添加python根目錄下的include文件夾;庫目錄添加python根目錄下的Lib文件夾。
lib文件夾裏放【python27.lib文件】和【python27_d.lib文件】,我現在debug32位下用的就是【python27_d.lib文件】。

2. 把【python27.dll文件】和C++要調用的【.py文件】都放到工程下debug文件夾下,也就是跟【.exe文件】相同目錄下。
當前還有python環境時,【python27.dll文件】在你安裝python後的C盤windows\SysWOW64文件夾下。

3. 在vs環境下調試時,需要將Python27文件夾放到調用python代碼的【.cpp文件】同目錄中;在軟件發佈後運行時,Python27文件夾放到【.exe文件】相同目錄下。

4. C++的代碼中添加Python.h頭文件。

【使用的幾個API函數】:
1. Py_SetPythonHome( "路徑")
    設置運行py文件時,搜索依賴文件的路徑。
2. Py_Initialize( )和Py_Finalize( )
    成對兒出現,用在調用python的頭尾。
3. PyImport_ImportModule("py的文件名")
    純文件名,不包含".py"這幾個字符,返回一個PyObject類型的指針,例如拿PyObject* pModule接收返回值。
4. PyObject_GetAttrString(pModule, "wcyaaa")
    拿到python中函數的索引,上面的pModule放到第一個參數,表示從這個py文件裏取數據;後面第二個參數是要調用的python函數的函數名。
    返回一個PyObject類型的指針,例如拿PyObject* pFunc接收返回值。
5. PyEval_CallObject(pFunc, NULL)

    調用pFunc對應的那個python中的函數,上面的pFunc放到第一個參數,表示調用這個函數;後面第二個參數是要傳入python函數的參數。這裏調用的是無參的函數,就填NULL。
    返回的內容爲python函數的返回值,類型仍是PyObject*。
6. PyTuple_New(參數個數)
    如果需要傳參數到python函數中,那這裏就將“傳參個數”設置成對應的數量。傳元組就類似C++中的const,不能改。
    返回值同樣是PyObject類型的指針,例如拿PyObject *pArgs接收返回值。

7. PyTuple_SetItem(pArgs, 0, variable)
    第一個參數就是負責傳遞參數的管道,也就是那個元組;第二個參數是這個元組中的第幾個元素;第三個參數是要放入元組對應位置的數據(這個需要是PyObject *)。
    調用函數傳參時,就這麼寫:PyEval_CallObject(pFunc, pArgs)
8. Py_BuildValue("i",variable)
    將C++的數據結構轉成python的數據結構。第一個參數是格式設定,第二個參數是待轉換的C++變量。
9. PyArg_Parse(pVal, "i", &result)
    將python的數據結構轉換成C++的數據結構。第一個參數是接收的python函數的返回值;第二個參數是參數設定;第三個參數是用來接收轉換後C++類型的數據。

【不安裝python環境運行】:
在運行python程序之前,也就是Py_Initialize( )之前調用一下Py_SetPythonHome( "路徑"),把搜索依賴文件的路徑設置成Python27文件夾的路徑,就ok了。

示例代碼裏面有很多不足:
比如構造二維嵌套的list時,直接粗暴的13個值塞進去了,其實可以分層來造;

包含的Python27文件夾中文件比較多,回頭再精簡一下。可根據下面幾個博客來嘗試提取。
嵌入python的c++程序發佈(二)最小化抽取需要的模塊 - CSDN博客
C中嵌入Python解釋器 - CSDN博客
VS2010 c++內嵌python環境以及生成發佈安裝包 - CSDN博客
嵌入python的c++程序發佈(一)最簡單的方法 - CSDN博客

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