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.

148
demandé sur Peter Mortensen 2008-10-31 05:01:48

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.

127
répondu paxdiablo 2016-04-04 01:33:59

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 et sub qui prennent deux arguments.

add(a, b) renvoie l'addition de deux nombres
sub(a, b) renvoie la soustraction de deux nombres

Le 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

51
répondu atul 2018-07-09 23:57:51

Les Ctypes peuvent être utilisés pour accéder aux DLL, voici un tutoriel:

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

7
répondu monkut 2008-10-31 02:18:03

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.

3
répondu David Nehme 2015-06-03 19:49:00

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)
3
répondu Carlos Gomez 2015-06-03 19:50:47