¿Cómo puedo utilizar un archivo DLL de Python?
¿ Cuál es la forma más sencilla de utilizar un DLL
archivo desde dentro Python
?
Específicamente, ¿cómo se puede hacer esto sin escribir ningún código contenedor adicional C++
para exponer la funcionalidad Python
?
Se prefiere la funcionalidad nativa Python
al uso de una biblioteca de terceros.
Para facilitar su uso, ctypes es el camino a seguir.
El siguiente ejemplo de ctypes proviene del código real que escribí (en Python 2.5). Esta ha sido, con diferencia, la forma más sencilla que he encontrado de hacer lo que me pides.
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))
El ctypes
material tiene todos los tipos de datos de tipo C ( ,,,, etc. int
) y puede pasar por valor o referencia. También puede devolver tipos de datos específicos, aunque mi ejemplo no lo hace (la API HLL devuelve valores modificando una variable pasada por referencia).char
short
void*
En términos del ejemplo específico mostrado arriba, EHLLAPI de IBM es una interfaz bastante consistente.
Todas las llamadas pasan cuatro punteros nulos (EHLLAPI envía el código de retorno a través del cuarto parámetro, un puntero a un int
modo, mientras especifico int
como tipo de retorno, puedo ignorarlo con seguridad) según la documentación de IBM aquí . En otras palabras, la variante C de la función sería:
int hllApi (void *p1, void *p2, void *p3, void *p4)
Esto crea una ctypes
función única y simple capaz de hacer cualquier cosa que proporcione la biblioteca EHLLAPI, pero es probable que otras bibliotecas necesiten una ctypes
función separada configurada para cada función de biblioteca.
El valor de retorno de WINFUNCTYPE
es un prototipo de función, pero aún debe configurar más información de parámetros (además de los tipos). Cada tupla hllApiParams
tiene un parámetro "dirección" (1 = entrada, 2 = salida, etc.), un nombre de parámetro y un valor predeterminado; consulte el ctypes
documento para obtener más detalles.
Una vez que tenga el prototipo y la información de los parámetros, puede crear un Python "invocable" hllApi
con el que llamar a la función. Simplemente crea la variable necesaria ( en mi caso, p1
hasta p4
) y llama a la función con ellas.
Esta página tiene un ejemplo muy simple de cómo llamar a funciones desde un archivo DLL.
Parafraseando los detalles aquí para que estén completos:
Es muy fácil llamar a una función DLL en Python. Tengo un archivo DLL hecho por mí mismo con dos funciones:
add
ysub
que toma dos argumentos.
add(a, b)
devuelve la suma de dos números
sub(a, b)
devuelve la resta de dos númerosEl nombre del archivo DLL será "demo.dll"
Programa:
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)
Producción:
Addition value:11 Substraction:9