C++開發python windows版本的擴展模塊示例
測試環境介紹和準備
測試環境:
操做系統:windows10
Python版本:3.7.0
VS版本:vs2015社區版(免費)
相關工具下載:
VS版本vs2015社區版(免費)
win10SDK(安裝vs2015是能夠選擇,若是沒有安裝則須要獨立安裝)
Python3.7.0 win32 安裝文件
http://ffmpeg.club/python
本示例不使用vs來編輯,但須要安裝vs的編譯環境,直接用python的distutils進行編譯安裝,注意這裏安裝的python是32位的,因此編譯出來庫也是32位程序。
首先要檢測系統中是否有其餘python版本,防止衝突
進入python命令行
import sys
print(sys.path)html
查看下當前系統路徑是否正確,若是是其餘路徑的版本,可能會對的擴展庫開發產生影響。主要是庫文件、頭文件、dll文件不一致的問題。 1 頭文件和庫文件 首先建立文件 mymod.c 在文件中添加頭文件引用 頭文件引用 #include "Python.h",庫文件不須要指定,頭文件路徑在python的安裝路徑。 2 定義模塊函數 其中函數參數 self是模塊自身,args是python傳遞的參數列表,返回值定義了一個×××數0,這裏會申請空間增長引用計數,交由python來管理這個引用。這裏也能夠返回NULL,python會收到一個異常。 #include "Python.h" ///模塊函數 static PyObject *testmod(PyObject *self,PyObject*args) { //返回python的long×××,c語言中引用計數+1,返回值交由python釋放 return PyLong_FromLong(0); }
3 申明模塊函數(開放給python)
第一個函數名稱,就是開放給python的名稱,不必定要與c語言的函數名稱一致,但仍是儘可能一致,方便跟進代碼;
第二個是函數指針,默認類型就是PyCFunction函數指針類型,也就是上面的函數類型;
第三個參數是開放給python的函數參數類型,這裏咱們設置的無參數METH_NOARGS,還能夠設置METH_VARARGS 多個參數,METH_KEYWORDS key value參數,設置爲METH_KEYWORDS必須與METH_VARARGS一塊兒設置 METH_KEYWORDS|METH_VARARGS ,而且模塊函數會增長一個參數存放傳進來的參數字典;
第四個參數是函數說明,在python中調用help函數能夠讀取;
這個定義是一個數據,能夠設置多個函數PyMethodDef定義對象
/// 模塊函數列表
static PyMethodDef mymod_funcs[] = {
{
"testmod", //函數名稱
testmod, //函數指針
METH_NOARGS,//參數標識 無參數,
"testmod function." //函數說明 help(testmod)
},
{0,0,0,0} //數組結尾,能夠申請多個函數
};
4 模塊定義
///4 模塊定義
static PyModuleDef mymod_module = {
PyModuleDef_HEAD_INIT,
"mymod", //模塊名
"mymod is first module test", //模塊說明 經過help(模塊名)
-1, //模塊空間,子解釋器用,-1不使用
mymod_funcs //模塊函數,前面定義的函數申明數組
};
5 添加入口函數
其中PyMODINIT_FUNC 宏在windows中是
PyMODINIT_FUNC declspec(dllexport) PyObject*,
也就是入口的動態連接庫函數,不一樣於ctypes庫,擴展庫只有入口函數須要定義declspec(dllexport)導出函數符號,其餘的函數不須要。
PyModuleCreate建立python的模塊,參數是前面定義的模塊,返回直接返回模塊對象,在python中全部類型均可以轉爲PyObject
///1 擴展庫入口函數 PyInit 固定的開頭 mymod模塊名
PyMODINIT_FUNC PyInit_mymod(void)
{
printf("PyInit_mymod\n");
///2 模塊建立函數 參數 PyModuleDef
return PyModule_Create(&mymod_module);
}
6 編譯安裝
建立一個文件setup.py
第一行代碼導入setup庫,其中name是打包的庫說明的.egg-info的文件名
version=「1.0」 這個說明文件名的後綴,若是不設置後綴會默認0.0.0
ext_modules=[Extension("mymod", ["mymod.c"] )] 中mymode是對應的模塊名稱和模塊文件名,["mymod.c"]裏面是編譯爲庫的源文件,能夠是多個文件,這裏是一個python的list數組。
from distutils.core import *
setup(
name="mymod", #打包文件名稱 庫說明文件的文件名
version="1.0",
ext_modules=[Extension("mymod", ["mymod.c"] )]
)
最後運行命令 python setup.py install
編譯成功,在當前路徑下會生成一個build目錄,裏面是編譯好的內容,應爲運行了install命令,因此不只作了編譯還有安裝。
擴展庫安裝的路徑:F:\Python-3.7.0\Lib\site-packagespython
7 擴展庫調用測試 擴展庫編譯和按照好後咱們寫一個python代碼來測試
這樣咱們就完成了咱們第一個python擴展庫的程序
http://edu.51cto.com/course/15278.htmlwindows