Jak mogę użyć pliku DLL z Pythona?

Jaki jest najprostszy sposób użycia pliku DLL z poziomu Pythona?

W szczególności, jak można to zrobić Bez pisania dodatkowego kodu wrappera C++, aby ujawnić funkcjonalność Pythonowi?

Natywna funkcjonalność Pythona jest zdecydowanie preferowana niż korzystanie z biblioteki innej firmy.

 148
Author: Peter Mortensen, 2008-10-31

5 answers

Dla łatwości użycia, ctypes jest drogą do zrobienia.

Poniższy przykład ctypów pochodzi z kodu, który napisałem (w Pythonie 2.5). To był, jak dotąd, najprostszy sposób, jaki znalazłem na robienie tego, o co prosisz.

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))

Rzeczy ctypes mają wszystkie typy danych Typu C (int, char, short, void*, i tak dalej) i może przejść przez wartość lub odniesienie. Może również zwracać określone typy danych, chociaż mój przykład tego nie robi (HLL API zwraca wartości modyfikując zmienna przekazywana przez referencję).


Jeśli chodzi o konkretny przykład pokazany powyżej, EHLLAPI IBM jest dość spójnym interfejsem.

Wszystkie wywołania przekazują cztery puste wskaźniki (EHLLAPI wysyła kod powrotu z powrotem przez czwarty parametr, wskaźnik do int, więc podczas gdy ja określam int jako typ powrotu, mogę go bezpiecznie zignorować) zgodnie z dokumentacją IBM tutaj . Innymi słowy, wariant C funkcji będzie:

int hllApi (void *p1, void *p2, void *p3, void *p4)

To sprawia, że dla jednego, prosta funkcja ctypes może zrobić wszystko, co biblioteka EHLLAPI zapewnia, ale jest prawdopodobne, że inne biblioteki będą potrzebować oddzielnej funkcji ctypes skonfigurowanej dla każdej funkcji bibliotecznej.

Wartość zwracana z WINFUNCTYPE jest prototypem funkcji, ale nadal musisz ustawić więcej informacji o parametrach(poza typami). Każda krotka w hllApiParams ma parametr "Kierunek" (1 = wejście, 2 = wyjście itd.), nazwę parametru i wartość domyślną-zobacz ctypes doco po szczegóły

Once masz informacje o prototypie i parametrach, możesz utworzyć Python "callable" hllApi, za pomocą którego można wywołać funkcję. Wystarczy utworzyć wymaganą zmienną (p1 poprzez p4 w moim przypadku) i wywołać funkcję z nimi.

 127
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-04 01:33:59

Ta strona zawiera bardzo prosty przykład wywoływania funkcji z pliku DLL.

Parafrazując szczegóły tutaj dla kompletności:

Bardzo łatwo jest wywołać funkcję DLL w Pythonie. Mam własny plik DLL z dwiema funkcjami: add i sub, które przyjmują dwa argumenty.

add(a, b) zwraca dodanie dwóch liczb
sub(a, b) zwraca odejmowanie dwóch liczb

Nazwa pliku DLL będzie brzmiała " demo.dll "

Program:

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

Wyjście:

Addition value:11
Substraction:9

 51
Author: atul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-09 23:57:51

Ctypes mogą być używane do dostępu do bibliotek DLL, oto Samouczek:

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

 7
Author: monkut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-31 02:18:03

Ctypes będzie najprostszą rzeczą w użyciu, ale (mis)używanie go sprawia, że Python podlega awarii. Jeśli próbujesz zrobić coś szybko i jesteś ostrożny, to świetnie.

Zachęcam do sprawdzenia Boost Python . Tak, wymaga napisania kodu C++ i posiadania kompilatora C++, ale tak naprawdę nie musisz uczyć się C++, aby go używać, a możesz dostać darmowy (jak w beer) kompilator C++ z Microsoft.

 3
Author: David Nehme,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-03 19:49:00

Może z Dispatch:

from win32com.client import Dispatch

zk = Dispatch("zkemkeeper.ZKEM") 

Gdzie zkemkeeper jest zarejestrowanym plikiem DLL w systemie... Następnie możesz uzyskać dostęp do funkcji, wywołując je:

zk.Connect_Net(IP_address, port)
 3
Author: Carlos Gomez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-03 19:50:47