[英]How can I use a DLL file from Python?
在Python
中使用DLL
文件的最簡單方法是什么?
具體來說,如何在不編寫任何額外的包裝C++
代碼以將功能公開給Python
的情況下做到這一點?
與使用第三方庫相比,本機Python
功能更受歡迎。
為了易於使用, ctypes是要走的路。
以下 ctypes 示例來自我編寫的實際代碼(在 Python 2.5 中)。 到目前為止,這是我找到的最簡單的方法,可以按照您的要求進行操作。
import ctypes
# Load DLL into memory.
hllDll = ctypes.WinDLL ("c:\\PComm\\ehlapi32.dll")
# Set up prototype and parameters for the desired function call.
# HLLAPI
hllApiProto = ctypes.WINFUNCTYPE (
ctypes.c_int, # Return type.
ctypes.c_void_p, # Parameters 1 ...
ctypes.c_void_p,
ctypes.c_void_p,
ctypes.c_void_p) # ... thru 4.
hllApiParams = (1, "p1", 0), (1, "p2", 0), (1, "p3",0), (1, "p4",0),
# Actually map the call ("HLLAPI(...)") to a Python name.
hllApi = hllApiProto (("HLLAPI", hllDll), hllApiParams)
# This is how you can actually call the DLL function.
# Set up the variables and call the Python name with them.
p1 = ctypes.c_int (1)
p2 = ctypes.c_char_p (sessionVar)
p3 = ctypes.c_int (1)
p4 = ctypes.c_int (0)
hllApi (ctypes.byref (p1), p2, ctypes.byref (p3), ctypes.byref (p4))
ctypes
的東西具有所有 C 類型數據類型( int
、 char
、 short
、 void*
等),並且可以按值或引用傳遞。 它也可以返回特定的數據類型,盡管我的示例沒有這樣做(HLL API 通過修改通過引用傳遞的變量來返回值)。
就上面展示的具體示例而言,IBM 的 EHLLAPI 是一個相當一致的接口。
根據 IBM 在此處的文檔,所有調用都傳遞四個 void 指針(EHLLAPI 通過第四個參數發送返回代碼,一個指向int
的指針,因此,當我將int
指定為返回類型時,我可以放心地忽略它)。 換句話說,該函數的 C 變體將是:
int hllApi (void *p1, void *p2, void *p3, void *p4)
這使得單個簡單的ctypes
函數能夠執行 EHLLAPI 庫提供的任何操作,但其他庫可能需要為每個庫函數設置單獨的ctypes
函數。
WINFUNCTYPE
的返回值是一個函數原型,但您仍然需要設置更多參數信息(超出類型)。 hllApiParams
中的每個元組都有一個參數“direction”(1 = 輸入,2 = 輸出等等)、一個參數名稱和一個默認值 - 有關詳細信息,請參閱ctypes
文檔
一旦你有了原型和參數信息,你就可以創建一個 Python “可調用” hllApi
來調用函數。 您只需創建所需的變量(在我的情況下為p1
到p4
)並使用它們調用函數。
這個頁面有一個從 DLL 文件調用函數的非常簡單的例子。
為了完整起見,在此處解釋詳細信息:
在 Python 中調用 DLL 函數非常容易。 我有一個自制的 DLL 文件,它有兩個函數:
add
和sub
,它們有兩個參數。
add(a, b)
返回兩個數字相加
sub(a, b)
返回兩個數字的減法DLL 文件的名稱將是“demo.dll”
程序:
from ctypes import*
# give location of dll
mydll = cdll.LoadLibrary("C:\\demo.dll")
result1= mydll.add(10,1)
result2= mydll.sub(10,1)
print "Addition value:"+result1
print "Substraction:"+result2
輸出:
Addition value:11
Substraction:9
我提供了一個完整的示例,說明如何通過ctypes
在Python
下構建shared library
並使用它。 我考慮Windows
案例並處理DLLs
。 需要兩個步驟:
我考慮的shared library
如下,包含在testDLL.cpp
文件中。 唯一的函數testDLL
只是接收一個int
並打印它。
#include <stdio.h>
extern "C" {
__declspec(dllexport)
void testDLL(const int i) {
printf("%d\n", i);
}
} // extern "C"
要從命令行運行使用Visual Studio
構建DLL
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\vsdevcmd"
設置包含路徑,然后運行
cl.exe /D_USRDLL /D_WINDLL testDLL.cpp /MT /link /DLL /OUT:testDLL.dll
構建 DLL。
DLL
或者,可以使用Visual Studio
構建DLL
,如下所示:
在 Python 下,執行以下操作
import os
import sys
from ctypes import *
lib = cdll.LoadLibrary('testDLL.dll')
lib.testDLL(3)
也許與Dispatch
:
from win32com.client import Dispatch
zk = Dispatch("zkemkeeper.ZKEM")
其中 zkemkeeper 是系統上注冊的 DLL 文件...之后,您可以通過調用它們來訪問函數:
zk.Connect_Net(IP_address, port)
ctypes 可用於訪問 dll,這里有一個教程:
ctypes 將是最容易使用的東西,但是(錯誤)使用它會使 Python 崩潰。 如果你想快速做某事,而且你很小心,那就太好了。
我鼓勵您查看Boost Python 。 是的,它要求您編寫一些 C++ 代碼並擁有 C++ 編譯器,但您實際上不需要學習 C++ 即可使用它,並且您可以從 Microsoft 獲得免費的(如啤酒中的)C++ 編譯器。
如果 DLL 是 COM 庫類型,那么您可以使用 pythonnet。
pip install pythonnet
然后在您的python代碼中,嘗試以下
import clr
clr.AddReference('path_to_your_dll')
# import the namespace and class
from Namespace import Class
# create an object of the class
obj = Class()
# access functions return type using object
value = obj.Function(<arguments>)
然后根據 DLL 中的類實例化一個對象,並訪問其中的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.