將python程序打包成DLL的三種方式
將python程序打包成DLL文件,然后用C++調用生成的DLL文件,這是一種用C++調用python的方法,這一塊比較容易遇到坑。
網(wǎng)上關于這一塊的教程不是很多,而且大部分都不能完全解決問題。
我在傻傻掙扎了幾天之后,終于試出了一個可行的版本,寫在這里供大家參考,也是供以后的自己參考。
Step1:用cython生成python腳本的.h和.c文件
首先我們要用到的一個工具叫cython,這個cython是python的第三方庫,需要我們用pip來安裝,這個對于會使用pyhton的人來說超級簡單,我在這里就不復述了。
安裝好cython之后,假如我們要用生成下面這個函數(shù)的dll文件。
def str_add(str1, str2): return int(str1) + int(str2)
我們只需要用vscode(或者是其他的python編譯器)生成一個.pyx文件,然后文件里面的內容如下。
cython: language_level=3 cdef public int str_add(const char* str1,const char* str2): return int(str1) + int(str2)
注意,一定要有第一行的內容(網(wǎng)上很多教程都忽覺了這個,可能導致不成功),如果你的電腦安裝的是python2,那么 language_level就要等于2。
編寫好.pyx文件(假如文件名為run.pyx)之后,然后我們在終端運行如下這句話。
cython run.pyx
運行之后,就會生成兩個文件,一個run.h,一個run.c。這兩個文件之后要用來生成dll文件。
Step2:生成dll文件
生成run.h和run.c文件之后,我們就可以用visual studio來生成dll文件了。
先建立一個win32的動態(tài)鏈接庫項目,然后配置好python環(huán)境。
如何配置python環(huán)境請參考這篇文章里面基本環(huán)境的搭建:http://www.dhdzp.com/article/275652.htm
然后在源文件下面建立一個dllmain.cpp的文件,文件里面的內容如下。
#include <Python.h>
#include <Windows.h>
#include "run.h"
extern "C"
{
__declspec(dllexport) int __stdcall _str_add(const char * a, const char * b) //聲明導出函數(shù),類,對象等供外面使用
{
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"); //這個要根據(jù)自己電腦python安裝的位置來
Py_Initialize();
//dll初始化的時候調用,這是python3的寫法,python2改成,initrun()。參見生成的run.h
PyInit_run();
break;
case DLL_PROCESS_DETACH:
Py_Finalize();
break;
}
return TRUE;
}
在網(wǎng)上的其他教程里面,一般會忽略Py_SetPath這一句,在我的電腦上,沒有這一句一定會出錯,這個坑是我找了好久才找出來的。
寫好之后,編譯即可生成dll文件(注意選擇好編譯環(huán)境,最好是Release環(huán)境下,如果你的電腦是X64,一定不要選成了X86哦,在上一步配置python環(huán)境的時候,也要注意和這個對應哦,別在debug下配置的python環(huán)境,然后在release下編譯哦)。
生成的dll文件一般在這個路徑之下。
項目目錄\\X64\\Release\\
Step3:測試dll文件
前兩步完成之后,我們就可以來測試生成的dll文件了。
首先,建立一個win32的控制臺項目。
然后將生成的dll文件復制到含源文件里面的.cpp文件的那個文件夾里。
然后在源文件里面創(chuàng)建一個.cpp文件,文件內容如下。
#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中需要調用的函數(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;
}
}
// 調用dll測試
//將字符變成int然后相加
system("pause");
return 0;
}
運行之后,結果如下。

總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
關于pytorch中網(wǎng)絡loss傳播和參數(shù)更新的理解
今天小編就為大家分享一篇關于pytorch中網(wǎng)絡loss傳播和參數(shù)更新的理解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08
Python中PDF解析利器pdfplumber的使用詳細教程
pdfplumber是一個Python庫,專門用于從PDF文件中提取文本、表格和其他信息,本文將為大家詳細介紹一下pdfplumber的安裝與詳細使用,有需要的小伙伴可以參考下2025-04-04

