1. 程式人生 > >C++開發python windows版本的擴充套件模組示例

C++開發python windows版本的擴充套件模組示例

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)
C++開發python windows版本的擴充套件模組示例

檢視下當前系統路徑是否正確,如果是其他路徑的版本,可能會對的擴充套件庫開發產生影響。主要是庫檔案、標頭檔案、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);
}

C++開發python windows版本的擴充套件模組示例
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} //陣列結尾,可以申請多個函式
};
C++開發python windows版本的擴充套件模組示例


4 模組定義
///4 模組定義
static PyModuleDef mymod_module = {
PyModuleDef_HEAD_INIT,
"mymod", //模組名
"mymod is first module test", //模組說明 通過help(模組名)
-1, //模組空間,子直譯器用,-1不使用
mymod_funcs //模組函式,前面定義的函式申明陣列
};
C++開發python windows版本的擴充套件模組示例
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);
}
C++開發python windows版本的擴充套件模組示例
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"] )]
)
C++開發python windows版本的擴充套件模組示例
最後執行命令 python setup.py install
C++開發python windows版本的擴充套件模組示例
編譯成功,在當前路徑下會生成一個build目錄,裡面是編譯好的內容,應為運行了install命令,所以不僅做了編譯還有安裝。
擴充套件庫安裝的路徑:F:\Python-3.7.0\Lib\site-packages
C++開發python windows版本的擴充套件模組示例

7 擴充套件庫呼叫測試
擴充套件庫編譯和按照好後我們寫一個python程式碼來測試

C++開發python windows版本的擴充套件模組示例
C++開發python windows版本的擴充套件模組示例

 這樣我們就完成了我們第一個python擴充套件庫的程式

http://edu.51cto.com/sd/f8c82

C++開發python windows版本的擴充套件模組示例