將python程序打包成DLL的三種方式
將python程序打包成DLL文件,然后用C++調(diào)用生成的DLL文件,這是一種用C++調(diào)用python的方法,這一塊比較容易遇到坑。
網(wǎng)上關(guān)于這一塊的教程不是很多,而且大部分都不能完全解決問(wèn)題。
我在傻傻掙扎了幾天之后,終于試出了一個(gè)可行的版本,寫(xiě)在這里供大家參考,也是供以后的自己參考。
Step1:用cython生成python腳本的.h和.c文件
首先我們要用到的一個(gè)工具叫cython,這個(gè)cython是python的第三方庫(kù),需要我們用pip來(lái)安裝,這個(gè)對(duì)于會(huì)使用pyhton的人來(lái)說(shuō)超級(jí)簡(jiǎn)單,我在這里就不復(fù)述了。
安裝好cython之后,假如我們要用生成下面這個(gè)函數(shù)的dll文件。
def str_add(str1, str2): return int(str1) + int(str2)
我們只需要用vscode(或者是其他的python編譯器)生成一個(gè).pyx文件,然后文件里面的內(nèi)容如下。
cython: language_level=3 cdef public int str_add(const char* str1,const char* str2): return int(str1) + int(str2)
注意,一定要有第一行的內(nèi)容(網(wǎng)上很多教程都忽覺(jué)了這個(gè),可能導(dǎo)致不成功),如果你的電腦安裝的是python2,那么 language_level就要等于2。
編寫(xiě)好.pyx文件(假如文件名為run.pyx)之后,然后我們?cè)诮K端運(yùn)行如下這句話。
cython run.pyx
運(yùn)行之后,就會(huì)生成兩個(gè)文件,一個(gè)run.h,一個(gè)run.c。這兩個(gè)文件之后要用來(lái)生成dll文件。
Step2:生成dll文件
生成run.h和run.c文件之后,我們就可以用visual studio來(lái)生成dll文件了。
先建立一個(gè)win32的動(dòng)態(tài)鏈接庫(kù)項(xiàng)目,然后配置好python環(huán)境。
如何配置python環(huán)境請(qǐng)參考這篇文章里面基本環(huán)境的搭建:http://www.dbjr.com.cn/article/275652.htm
然后在源文件下面建立一個(gè)dllmain.cpp的文件,文件里面的內(nèi)容如下。
#include <Python.h> #include <Windows.h> #include "run.h" extern "C" { __declspec(dllexport) int __stdcall _str_add(const char * a, const char * b) //聲明導(dǎo)出函數(shù),類(lèi),對(duì)象等供外面使用 { return str_add(a, b); } } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: Py_SetPath(L"D:/chengxuanzhuang/anaconda/envs/python3.6/Lib"); //這個(gè)要根據(jù)自己電腦python安裝的位置來(lái) Py_Initialize(); //dll初始化的時(shí)候調(diào)用,這是python3的寫(xiě)法,python2改成,initrun()。參見(jiàn)生成的run.h PyInit_run(); break; case DLL_PROCESS_DETACH: Py_Finalize(); break; } return TRUE; }
在網(wǎng)上的其他教程里面,一般會(huì)忽略Py_SetPath這一句,在我的電腦上,沒(méi)有這一句一定會(huì)出錯(cuò),這個(gè)坑是我找了好久才找出來(lái)的。
寫(xiě)好之后,編譯即可生成dll文件(注意選擇好編譯環(huán)境,最好是Release環(huán)境下,如果你的電腦是X64,一定不要選成了X86哦,在上一步配置python環(huán)境的時(shí)候,也要注意和這個(gè)對(duì)應(yīng)哦,別在debug下配置的python環(huán)境,然后在release下編譯哦)。
生成的dll文件一般在這個(gè)路徑之下。
項(xiàng)目目錄\\X64\\Release\\
Step3:測(cè)試dll文件
前兩步完成之后,我們就可以來(lái)測(cè)試生成的dll文件了。
首先,建立一個(gè)win32的控制臺(tái)項(xiàng)目。
然后將生成的dll文件復(fù)制到含源文件里面的.cpp文件的那個(gè)文件夾里。
然后在源文件里面創(chuàng)建一個(gè).cpp文件,文件內(nèi)容如下。
#include <Windows.h> #include <iostream> #include <tchar.h> using namespace std; int main() { typedef int(*pAdd)(const char * a, const char * b); HINSTANCE hDLL = LoadLibrary(_T("python_to_DLL.dll")); cout << "hDLL:" << hDLL << endl; if (hDLL) { // 獲取DLL中需要調(diào)用的函數(shù)的地址 pAdd pFun = (pAdd)GetProcAddress(hDLL, "_str_add"); cout << "pFun:" << pFun << endl; const char* stra = "12"; const char* strb = "22"; if (pFun) { int i = pFun(stra, strb); cout << "i = " << i << endl; } } // 調(diào)用dll測(cè)試 //將字符變成int然后相加 system("pause"); return 0; }
運(yùn)行之后,結(jié)果如下。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
python 使用OpenCV進(jìn)行簡(jiǎn)單的人像分割與合成
這篇文章主要介紹了python 使用OpenCV進(jìn)行簡(jiǎn)單的人像分割與合成的方法,幫助大家更好的利用python處理圖像,感興趣的朋友可以了解下2021-02-02python實(shí)現(xiàn)登陸知乎獲得個(gè)人收藏并保存為word文件
這篇文章主要介紹了python實(shí)現(xiàn)登陸知乎獲得個(gè)人收藏并保存為word文件,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-03-03Python爬取科目四考試題庫(kù)的方法實(shí)現(xiàn)
這篇文章主要介紹了Python爬取科目四考試題庫(kù)的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03python對(duì)json的相關(guān)操作實(shí)例詳解
這篇文章主要介紹了python對(duì)json的相關(guān)操作,結(jié)合實(shí)例形式詳細(xì)分析了json的概念、功能以及Python針對(duì)json的解析、輸出、排序、轉(zhuǎn)換等操作技巧,需要的朋友可以參考下2017-01-01Python發(fā)送手機(jī)動(dòng)態(tài)驗(yàn)證碼代碼實(shí)例
這篇文章主要介紹了Python發(fā)送手機(jī)動(dòng)態(tài)驗(yàn)證碼代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02一步步教你用Python實(shí)現(xiàn)2048小游戲
相信2048這個(gè)游戲?qū)Υ蠹襾?lái)說(shuō)一定不陌生,下面這篇文章就主要給大家介紹了怎么用Python實(shí)現(xiàn)2048小游戲,文中通過(guò)注釋與示例代碼介紹的很詳細(xì),相信對(duì)大家的理解和學(xué)習(xí)具有一定的參考借鑒價(jià)值,有需要的朋友們一起來(lái)看看吧。2017-01-01Python實(shí)現(xiàn)操縱控制windows注冊(cè)表的方法分析
這篇文章主要介紹了Python實(shí)現(xiàn)操縱控制windows注冊(cè)表的方法,結(jié)合實(shí)例形式分析了Python使用_winreg模塊以及win32api模塊針對(duì)Windows注冊(cè)表操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-05-05