簡體   English   中英

如何使用 Python 中的 DLL 文件?

[英]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 類型數據類型( intcharshortvoid*等),並且可以按值或引用傳遞。 它也可以返回特定的數據類型,盡管我的示例沒有這樣做(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來調用函數。 您只需創建所需的變量(在我的情況下為p1p4 )並使用它們調用函數。

這個頁面有一個從 DLL 文件調用函數的非常簡單的例子。

為了完整起見,在此處解釋詳細信息:

在 Python 中調用 DLL 函數非常容易。 我有一個自制的 DLL 文件,它有兩個函數: addsub ,它們有兩個參數。

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 下構建 DLL 並鏈接它

我提供了一個完整的示例,說明如何通過ctypesPython下構建shared library並使用它。 我考慮Windows案例並處理DLLs 需要兩個步驟:

  1. 使用 Visual Studio 的編譯器從命令行或 IDE 構建 DLL;
  2. 使用 ctypes 在 Python 下鏈接 DLL。

共享庫

我考慮的shared library如下,包含在testDLL.cpp文件中。 唯一的函數testDLL只是接收一個int並打印它。

#include <stdio.h>
​
extern "C" {
​
__declspec(dllexport)
​
void testDLL(const int i) {
    printf("%d\n", i);
}
​
} // extern "C"

從命令行構建 DLL

要從命令行運行使用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。

從 IDE 構建DLL

或者,可以使用Visual Studio構建DLL ,如下所示:

  1. 文件->新建->項目;
  2. 已安裝 -> 模板 -> Visual C++ -> Windows -> Win32 -> Win32Project;
  3. 下一個;
  4. 應用程序類型 -> DLL;
  5. 附加選項 -> 空項目(選擇);
  6. 附加選項 -> 預編譯頭(取消選擇);
  7. 項目 -> 屬性 -> 配置管理器 -> 活動解決方案平台:x64;
  8. 項目 -> 屬性 -> 配置管理器 -> 活動解決方案配置:發布。

Python下鏈接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,這里有一個教程:

http://docs.python.org/library/ctypes.html#module-ctypes

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM