Comment puis-je utiliser un fichier DLL de Python?
Quel est le moyen le plus simple d'utiliser un fichier DLL à partir de Python?
Plus précisément, comment cela peut-il être fait Sans écrire du code C++ wrapper supplémentaire pour exposer la fonctionnalité à Python?
La fonctionnalité Python Native est fortement préférée à l'utilisation d'une bibliothèque tierce.
5 réponses
Pour la facilité d'utilisation, ctypes est le chemin à parcourir.
L'exemple suivant de ctypes provient du code réel que j'ai écrit (en python 2.5). Cela a été, de loin, le moyen le plus facile que j'ai trouvé pour faire ce que vous demandez.
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))
Le truc ctypes
a tous les types de données de type C(int
, char
, short
, void*
, et ainsi de suite) et peut passer par valeur ou référence. Il peut également renvoyer des types de données spécifiques bien que mon exemple ne le fasse pas (L'API HLL renvoie des valeurs en modifiant un variable passée par référence).
En termes d'exemple spécifique montré ci-dessus, EHLAPI D'IBM est une interface assez cohérente.
Tous les appels passent quatre pointeurs void (EHLLAPI renvoie le code de retour via le quatrième paramètre, un pointeur vers un int
donc, alors que je spécifie {[3] } comme type de retour, je peux l'ignorer en toute sécurité) selon la documentation D'IBM ici. En d'autres termes, la variante C de la fonction serait:
int hllApi (void *p1, void *p2, void *p3, void *p4)
Cela fait pour un seul, FONCTION simple ctypes
capable de faire tout ce que la bibliothèque EHLLAPI fournit, mais il est probable que d'autres bibliothèques auront besoin d'une fonction ctypes
distincte configurée par fonction de bibliothèque.
La valeur de retour de WINFUNCTYPE
est un prototype de fonction mais vous devez toujours configurer plus d'informations sur les paramètres (au-delà des types). Chaque tuple dans hllApiParams
a un paramètre" direction " (1 = Entrée, 2 = sortie et ainsi de suite), un nom de paramètre et une valeur par défaut - voir la doco ctypes
pour plus de détails
Une fois vous avez le prototype et les informations de paramètre, vous pouvez créer un Python "callable" hllApi
avec lequel appeler la fonction. Vous créez simplement la variable nécessaire (p1
à travers p4
dans mon cas) et appelez la fonction avec eux.
Cette page a un exemple très simple d'appel de fonctions à partir d'un fichier DLL.
Paraphraser les détails ici pour être complet:
Il est très facile d'appeler une fonction DLL en Python. J'ai un fichier DLL self-made avec deux fonctions:
add
etsub
qui prennent deux arguments.
add(a, b)
renvoie l'addition de deux nombressub(a, b)
renvoie la soustraction de deux nombresLe nom du fichier DLL sera " demo.dll "
Programme:
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
Sortie:
Addition value:11
Substraction:9
Les Ctypes peuvent être utilisés pour accéder aux DLL, voici un tutoriel:
Ctypes sera la chose la plus facile à utiliser, mais (mal)l'utiliser rend Python sujet à un plantage. Si vous essayez de faire quelque chose rapidement et que vous faites attention, c'est génial.
Je vous encourage à vérifier Boost Python. Oui, cela nécessite que vous écriviez du code C++ et ayez un compilateur C++, mais vous n'avez pas vraiment besoin d'apprendre le C++ pour l'utiliser, et vous pouvez obtenir un compilateur C++ GRATUIT (comme dans beer) de Microsoft.
Peut-être avec Dispatch
:
from win32com.client import Dispatch
zk = Dispatch("zkemkeeper.ZKEM")
Où zkemkeeper est un fichier DLL enregistré sur le système... Après cela, vous pouvez accéder aux fonctions simplement en les appelant:
zk.Connect_Net(IP_address, port)