python3在windows下三種方法使用C擴充套件
一、前言
python有時候需要用到c或者c++的庫,這裡我們將介紹三種呼叫c擴充套件的方法。分別用swig,stypes,和python C擴充套件。三種方法各有優缺點,但第三種方法最為常用。我使用到的平臺為windows10,python3.6 ,vs2015
二、swig呼叫c擴充套件
首先介紹第一種方法,這裡我參考了兩篇部落格:“https://www.jianshu.com/p/a257e630fe42Windows平臺下Python使用swig呼叫C++ ”和 “https://blog.csdn.net/g0ose/article/details/80415602
1、下載安裝swig
首先在 www.swig.org 下載swig安裝包,解壓安裝包到任意路徑,路徑中最好不要帶空格。完成之後,將swig.exe所在的路徑新增環境路徑中。具體過程如下:
step1 安裝下載:進入官網->點選“download”->點選“download area”->點選“ swigwin-3.0.12
step2 新增到環境路徑:右擊我的電腦->選擇屬性->選擇高階系統設定->環境變數->雙擊系統變數裡面的path->編輯將swig.exe所在的目錄新增進去即可。截圖如下:
2、準備c++/c程式碼和介面檔案(這裡我用的是c++版本)。
建立c++的原始檔、標頭檔案以及swig介面檔案:jsample.cpp,jsample.h,三個檔案如下:
/* jsample.h */ #ifndef JSAMPLE_H #define JSAMPLE_H //void cHelloWorld(); int compute(int a, int b); #endif
/* jsample.cpp */
#include <iostream>
#include "jsample.h"
using namespace std;
int compute(int a, int b)
{
int temp = (a+b)*(a-b);
return temp;
}
/* File : jsample.i */
%module jsample
%inline %{
#include "jsample.h"
%}
int compute(int a,int b);
可以用記事本來建立這三個檔案,方法如下:以jsample.cpp為例,首先新建一個記事本檔案,命名為jsample,輸完內容之後,另存為jsample.cpp(注意後面要加.cpp),儲存型別為“所有檔案”。另外兩個也是類似的,最後生成的檔案結果如下:
3、使用swig生成部分檔案
開啟cmd,進入jsample.i檔案所在的目錄(三個檔案要在同一個目錄下)。輸入:swig -python -c++ jsample.i如果是c的話就不需要新增c++了。(要注意python要寫在前面,c++寫在後面,否則可能會出錯)
執行完成之後,在資料夾中就會多出兩個檔案了。如下圖:
4、使用vs編譯檔案(我使用的是vs2015)
step1:新建c++工程專案
新建專案,選擇win32控制檯應用程式,輸入工程名稱,我命名為test.
點選下一步,應用程式型別選擇dll,附加選項選擇空專案。
點選完成之後,將檔案拖到工程檔案中,檔案會自動放置在對應的位置。
step2:配置vs環境
配置管理設定為:活動解決方案配置設為Release,活動解決方案平臺設定為x64(本機為64位)
方法如下:
- 修改目標輸出檔案:目標檔名在$(ProjectName)前面加上下劃線_,目標副檔名將.dll改成.pyd。(這一步可以在生成解決方案之後直接修改檔名稱也可以)。
- 配置標頭檔案:專案->屬性->VC++目錄->包含目錄
如果缺少上面這一步的話就會出現以下錯誤,無法匯入python包.
- 配置庫:專案->屬性->新增庫目錄
step3:生成解決方案
生成->生成解決方案。成功後,開啟工程資料夾,x64下的release中有一個_test.pyd檔案。然後將檔名改成_jsample,然後放在之前swig生成的jsample.py檔案一起。(非常抱歉,這裡我走了彎路,實際上只需要將vs中的工程名直接設定為jsample就可以了)
5、測試使用
需要執行這個jsample.py這個檔案,只需要兩個檔案:jsample.py和_jsample.pyd,其他的都可以不用了。下面我們來用cmd命令測試一下,如果是在pycharm中使用,只需要將這兩個檔案一起放在工程工程夾下就可以了。
cmd命令執行:
開啟cmd命令,進入到jsample.py資料夾下,執行python,輸入下面的程式碼:
import jsample
print('this is the test running.\n')
aa = jsample.compute(5,2)
print(aa)
可以看到,執行結果如下:
這說明程式已經成功了。