¿Cómo puedo utilizar un archivo DLL de Python?

Resuelto Tom Hennen asked hace 15 años • 6 respuestas

¿ Cuál es la forma más sencilla de utilizar un DLLarchivo 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 Pythonal uso de una biblioteca de terceros.

Tom Hennen avatar Oct 31 '08 09:10 Tom Hennen
Aceptado

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 ctypesmaterial 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).charshortvoid*


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 intmodo, mientras especifico intcomo 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 ctypesfunción única y simple capaz de hacer cualquier cosa que proporcione la biblioteca EHLLAPI, pero es probable que otras bibliotecas necesiten una ctypesfunción separada configurada para cada función de biblioteca.

El valor de retorno de WINFUNCTYPEes un prototipo de función, pero aún debe configurar más información de parámetros (además de los tipos). Cada tupla hllApiParamstiene un parámetro "dirección" (1 = entrada, 2 = salida, etc.), un nombre de parámetro y un valor predeterminado; consulte el ctypesdocumento para obtener más detalles.

Una vez que tenga el prototipo y la información de los parámetros, puede crear un Python "invocable" hllApicon el que llamar a la función. Simplemente crea la variable necesaria ( en mi caso, p1hasta p4) y llama a la función con ellas.

paxdiablo avatar Oct 31 '2008 02:10 paxdiablo

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: addy subque toma dos argumentos.

add(a, b)devuelve la suma de dos números
sub(a, b)devuelve la resta de dos números

El 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
atul avatar Jul 04 '2010 06:07 atul