python使用ctypes呼叫擴充套件模組的例項方法
我們知道python的執行效率不是很高,而且由於GIL的原因,導致python不能充分利用多核CPU。一般的解決方式是使用多程式,但是多程式開銷比較大,而且程式之間的通訊也會比較麻煩。因此在解決效率問題上,我們會把那些比較耗時的模組使用C或者C++編寫,然後編譯成動態連結庫,Windows上面是dll,linux上面則是so,編譯好之後,交給python去呼叫。而且透過擴充套件模組的方式還可以解決python的GIL的問題,因此如果想要利用多核,我們仍然可以透過擴充套件模組的方式。
python如何呼叫擴充套件模組
python呼叫擴充套件模組的一種比較簡單的方式就是使用ctypes這個庫,這個庫是python官方提供的,任何一個版本的python都可以使用,我們透過ctypes可以很輕鬆地呼叫擴充套件模組。
演示
#include <stdio.h> void test() { printf("hello world\n"); }
我們定義了一個很簡單的函式,下面我們就可以將其編譯成擴充套件模組了。在Windows是dll,linux上是so,編譯的命令是一樣的。我這裡以Windows 為例,記得在Windows上要安裝MinGW,或者安裝VsCode,我這裡使用的是MinGW,因為VsCode太大了。
gcc -o dll檔案或者so檔案 -shared c或者c++原始檔
我這裡的C原始檔叫做1.c,我們編譯成mmp.dll吧,所以命令就可以這麼寫:gcc -o mmp.dll -shared 1.c
下面就可以使用python去呼叫了。
import ctypes # 使用ctypes很簡單,直接import進來,然後使用ctypes.CDLL這個類來載入動態模組 # 如果在Windows上還可以使用ctypes.WinDLL。 # 因為看ctypes原始碼的話,會發現WinDLL也是一個類並且繼承自CDLL # 所以在linux上使用ctypes.CDLL, # 而在Windows上既可以使用WinDLL、也可以使用CDLL載入動態模組 lib = ctypes.CDLL("./mmp.dll") # 載入之後就得到了擴充套件模組 # 我們可以直接透過.的方式去呼叫裡面的函式了,會發現成功列印 lib.test() # hello world # 但是為了確定是否存在這個函式,我們一般會使用反射去獲取 # 因為如果函式不存在透過.的方式呼叫會拋異常的 func = getattr(lib, "test", None) if func: print(func) # <_FuncPtr object at 0x0000029F75F315F0> func() # hello world # 不存在test_xx這個函式,所以得到的結果為None func1 = getattr(lib, "test_xx", None) print(func1) # None
所以使用ctypes去呼叫擴充套件模組非常方便
1.透過ctypes.CDLL("dll或者so的路徑"),如果是Windows還可以使用ctypes.WinDLL("dll路徑")。另外這兩種載入方式分別等價於:ctypes.CDLL("dll或者so的路徑") == ctypes.cdll.LoadLibrary("dll或者so的路徑"),ctypes.WinDLL("dll路徑") == ctypes.windll.LoadLibrary("dll路徑")。但是注意的是:linux上只能使用ctypes.CDLL和ctypes.cdll.LoadLibrary,而Windows上ctypes.CDLL、ctypes.cdll.LoadLibrary、ctypes.WinDLL、ctypes.windll.LoadLibrary都可以使用。但是一般我們都使用ctypes.CDLL即可,另外注意的是:dll或者so檔案的路徑最好是絕對路徑,即便不是也要表明層級,比如我們這裡的py檔案和dll檔案是在同一個目錄下,但是我們載入的時候不可以寫mmp.dll,這樣會報錯找不到,要寫成./mmp.dll。
2.載入動態模組之後會返回一個物件,我們上面起名為lib,這個lib就是得到的擴充套件模組了。
3.然後可以直接透過lib呼叫裡面的函式,但是一般我們會使用反射的方式來獲取,因為不知道函式到底存不存在,如果不存在直接呼叫會丟擲異常,如果存在這個函式我們才會執行。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69993754/viewspace-2752782/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 使用ctypes來擴充套件Python套件Python
- 【IDL】 DICOM擴充套件模組套件
- 【PHP】Mcrypt 擴充套件模組安裝及使用PHP套件
- 使用 Python 擴充套件豐富 UiBot 的功能及在 UiBot 中引用 Python 模組Python套件UI
- 使用cython擴充套件python庫套件Python
- 使用udev擴充套件ASM磁碟組dev套件ASM
- Flutter——Dart Extension擴充套件方法的使用FlutterDart套件
- Java 中模擬 C# 的擴充套件方法JavaC#套件
- tonyenc加密擴充套件使用方法加密套件
- (PHP7核心剖析-11) 模組擴充套件PHP套件
- Json擴充套件方法JSON套件
- LINQ擴充套件方法套件
- [譯] 探索 SMACSS:可擴充套件的模組化 CSS 框架MacCSS套件框架
- 智聯招聘的Web模組擴充套件落地方案Web套件
- Pybind11和CMake構建python擴充套件模組環境搭建Python套件
- python呼叫方法必須例項化麼Python
- .Net Core AutoMapper自定義擴充套件方法的使用APP套件
- android view 擴充套件方法AndroidView套件
- 使用Kotlin擴充套件函式擴充套件Spring Data案例Kotlin套件函式Spring
- Java 缺失的特性:擴充套件方法Java套件
- vue-cli webpack3 擴充套件多模組打包VueWeb套件
- 使用 Cython 為 Python 編寫更快的 C 擴充套件Python套件
- 在Python中呼叫Java擴充套件包HanLP測試記錄PythonJava套件HanLP
- 實用的可選項(Optional)擴充套件套件
- kotlin 擴充套件(擴充套件函式和擴充套件屬性)Kotlin套件函式
- [譯]使用JavaScript建立WebAssembly模組例項JavaScriptWeb
- 再學Blazor——擴充套件方法Blazor套件
- Solon詳解(六)- Solon的校驗擴充套件框架使用與擴充套件套件框架
- Python與C/C++呼叫之ctypesPythonC++
- testng擴充套件 失敗的用例重跑套件
- [外掛擴充套件]先佔樓做一個快遞的模組套件
- R呼叫python模組Python
- ?Slow Admin v1.5.* 版本釋出, 新增擴充套件管理模組套件
- C# 反射呼叫擴充類方法C#反射
- Source insight擴充套件宏使用套件
- gpexpand擴充gp例項和節點
- burpsuite擴充套件開發之PythonUI套件Python
- Python為什麼能擴充套件Python套件