web-dev-qa-db-fra.com

Comment utiliser un fichier DLL à partir 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 additionnel C++ pour emballer afin d'exposer la fonctionnalité à Python?

La fonctionnalité native Python est fortement préférable à l'utilisation d'une bibliothèque tierce.

168
Tom Hennen

Pour plus de facilité, ctypes est la voie à suivre.

L'exemple suivant de ctypes provient du code que j'ai écrit (dans Python 2.5). C'est de loin le moyen le plus simple 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))

La substance ctypes a tous les types de données de type C (int, char, short, void*, etc.) et peut passer par valeur ou référence. Elle peut également renvoyer des types de données spécifiques, mais mon exemple ne le fait pas (l'API HLL renvoie des valeurs en modifiant une variable passée par référence).


En ce qui concerne l'exemple spécifique présenté ci-dessus, l'interface EHLLAPI d'IBM est une interface relativement cohérente.

Tous les appels transmettent quatre pointeurs vides (EHLLAPI renvoie le code de retour via le quatrième paramètre, un pointeur sur un int, de sorte que, si je spécifie int comme type de retour, je peux l'ignorer en toute sécurité) conformément à 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 donne une fonction simple et 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 (en plus des types). Chaque Tuple dans hllApiParams a un paramètre "direction" (1 = entrée, 2 = sortie, etc.), un nom de paramètre et une valeur par défaut - voir le doco ctypes pour plus de détails

Une fois que vous avez les informations relatives au prototype et aux paramètres, vous pouvez créer un Python "appelable" hllApi avec lequel appeler la fonction. Vous créez simplement la variable nécessaire (p1 à p4 dans mon cas) et appelez la fonction avec eux.

141
paxdiablo

Cette page présente un exemple très simple d’appel de fonctions à partir d’un fichier DLL.

Paraphrasant les détails ici pour plus de détails:

Il est très facile d'appeler une fonction DLL en Python. J'ai un fichier DLL créé de manière autonome avec deux fonctions: add et sub qui prennent deux arguments.

add(a, b) retourne l'ajout 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

60
atul

ctypes peut être utilisé pour accéder aux dll, voici un tutoriel:

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

7
monkut

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)
6
Carlos Gomez

ctypes sera la chose la plus facile à utiliser, mais son utilisation (mal) rend Python sujet à un crash. Si vous essayez de faire quelque chose rapidement et que vous faites attention, c'est génial.

Je vous encourage à consulter Boost Python . Oui, cela nécessite que vous écriviez du code C++ et que vous disposiez d'un compilateur C++, mais vous n'avez pas besoin d'apprendre le C++ pour l'utiliser, et vous pouvez en obtenir un gratuitement (comme dans beer) Compilateur C++ de Microsoft .

3
David Nehme

Construire un DLL et le lier sous Python à l'aide de ctypes

Je présente un exemple complet sur la manière de construire un shared library et de l’utiliser sous Python au moyen de ctypes. Je considère le cas Windows et traite DLLs. Deux étapes sont nécessaires:

  1. Construisez le DLL à l'aide du compilateur de Visual Studio à partir de la ligne de commande ou de l'EDI;
  2. Liez le DLL sous Python à l'aide de ctypes.

La bibliothèque partagée

Le shared library que j'estime est le suivant et est contenu dans le fichier testDLL.cpp. La seule fonction testDLL reçoit juste un int et l’imprime.

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

Construire le DLL à partir de la ligne de commande

Pour construire une DLL avec Visual Studio à partir de la ligne de commande, exécutez

"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\vsdevcmd"

pour définir le chemin d'inclusion et ensuite exécuter

cl.exe /D_USRDLL /D_WINDLL testDLL.cpp /MT /link /DLL /OUT:testDLL.dll

pour construire la DLL.

Construire la DLL à partir de l'IDE

Sinon, la DLL peut être construite en utilisant Visual Studio comme suit:

  1. Fichier -> Nouveau -> Projet;
  2. Installé -> Modèles -> Visual C++ -> Windows -> Win32 -> Win32Project;
  3. Prochain;
  4. Type d'application -> DLL;
  5. Options supplémentaires -> Projet vide (sélectionner);
  6. Options supplémentaires -> En-tête précompilé (désélectionner);
  7. Projet -> Propriétés -> Configuration Manager -> Plate-forme de solution active: x64;
  8. Projet -> Propriétés -> Gestionnaire de configuration -> Configuration de la solution active: Validez.

Lier le DLL sous Python

Sous Python, procédez comme suit

import os
import sys
from ctypes import *

lib = cdll.LoadLibrary('testDLL.dll')

lib.testDLL(3)
2
JackOLantern