2008-10-31 27 views
136

¿Cuál es la forma más fácil de usar un archivo DLL desde Python?¿Cómo puedo usar un archivo DLL de Python?

Específicamente, ¿cómo se puede hacer esto sin escribiendo ningún código C++ contenedor adicional para exponer la funcionalidad a Python?

La funcionalidad nativa de Python es muy preferible a usar una biblioteca de terceros.

+0

@Remuze tenía que etiquetar la pregunta equivocada o etiqueta con la respuesta incorrecta? Ambos son pitón, pero no veo ninguna razón para que los encuentres en absoluto similares (y revisé el historial de revisión para asegurarme de que de alguna manera no estaba más cerca en algún momento del pasado) – Foon

+0

@foon hmmm sí lo siento, Quería marcar otra pregunta como duplicada y poner esta :) ¡Supongo que eso demuestra lo similares que son! –

Respuesta

113

Para facilidad de uso, ctypes es el camino a seguir.

El siguiente ejemplo de ctypes es del código real que he escrito (en Python 2.5). Esta ha sido, de lejos, la forma más fácil que he encontrado para 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)) 

La materia ctypes tiene todos los tipos de datos de tipo C (int, char, short, void*, etc.) 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 mediante la modificación de una variable pasada por referencia).


En términos del ejemplo específico mostrado anteriormente, EHLLAPI de IBM es una interfaz bastante consistente.

Todas las llamadas pasan cuatro punteros void (EHLLAPI envía el código de retorno de nuevo a través del cuarto parámetro, un puntero a un int así, mientras que especifico int como el tipo de retorno, que puede pasar por alto que) de acuerdo con la documentación de IBM here. En otras palabras, la variante C de la función sería:

int hllApi (void *p1, void *p2, void *p3, void *p4) 

Esto hace que para una sola función simple, ctypes capaz de hacer cualquier cosa la biblioteca EHLLAPI ofrece, pero es probable que otras bibliotecas tendrán una función separada ctypes configurar por 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 (por encima de los tipos). Cada tupla en hllApiParams tiene una "dirección" de parámetros (1 = entrada, 2 = salida y así sucesivamente), un nombre de parámetro y un valor por defecto - ver el mana ctypes para más detalles

Una vez que tenga la información de prototipo y de parámetros, puede crear un Python "invocable" hllApi con el que llamar a la función. Simplemente cree la variable necesaria (p1 hasta p4 en mi caso) y llame a la función con ellos.

+0

Sí, ctypes es genial. Python ha sido bendecido con una gran forma incorporada (desde 2.5) de acceder al código en DLL. ctypes es tan fácil de usar que tienes que pensar dos veces antes de escribir extensiones reales, en lugar de solo proporcionar un módulo de Python puro que use ctypes para interactuar con tu DLL. –

+1

Hola, puede que haya pasado mucho tiempo desde que alguien respondió aquí, pero quería saber algo para que esto funcione exactamente para mi programa. ¿Podría decirme qué es "HLLAPI" en esto? Además, si quiero acceder a mi dll con una función "nulo BoxProperties (doble L, doble H, doble W, doble y A, doble &V);) ¿podría sugerirme qué cambios debería hacer al código anterior para que funcione? ? Cheers. – Neophile

+3

¿Qué hace exactamente 'hllApiParams'? ¿Cuál es el punto de esas tuplas? Es difícil hacer coincidir algunas de las cosas en este ejemplo con la documentación. –

2

ctypes serán lo más fácil de usar, pero el (mal) uso que hace Python sujetos a estrellarse. Si tratas de hacer algo rápidamente y eres cuidadoso, es genial.

Lo invito a consultar Boost Python. Sí, requiere que escriba algún código C++ y tenga un compilador C++, pero en realidad no necesita aprender C++ para usarlo, y puede obtener un código gratuito (como en beer) C++ compiler from Microsoft.

45

This page es un ejemplo muy simple de funciones de llamada desde un archivo DLL.

Es muy fácil llamar a una función DLL en Python. Tengo un archivo DLL hecho a sí mismo con dos funciones: add y sub que toman dos argumentos.

add(a, b) devuelve suma de dos números
sub(a, b) vuelve 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

Salida:

Addition value:-11
Substraction:-9

+2

El enlace en esta respuesta está roto. – Kaliber64

+0

El enlace funcionó para mí – Inversus

+3

Si el enlace no funciona para usted, no se preocupe, se trata de una copia directa pegar. No te falta información. – marsh

3

Tal vez con Dispatch:

from win32com.client import Dispatch 

zk = Dispatch("zkemkeeper.ZKEM") 

Dónde zkemkeeper es un archivo DLL registrado en el sistema ... Después de eso, se puede acceder a las funciones con sólo llamarlos:

zk.Connect_Net(IP_address, port) 
Cuestiones relacionadas