Как я могу использовать файл DLL из Python?
Какой самый простой способ использовать файл DLL из Python?
В частности, как это можно сделать без написания какого-либо дополнительного кода обёртки C++ для предоставления функциональности Python?
Встроенная функциональность Python настоятельно предпочтительнее, чем использование сторонней библиотеки.
5 ответов
Для простоты использования, ctypes - это путь.
Следующий пример ctypes взят из реального кода, который я написал (в Python 2.5). Это, безусловно, самый простой способ, который я нашел для выполнения того, что вы просите.
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))
ctypes
материал имеет все типы данных C-типа (int
, char
, short
, void*
и т. д.) и может передаваться по значению или по ссылке. Он также может возвращать определенные типы данных, хотя мой пример этого не делает (HLL API возвращает значения путем изменения переменной, переданной по ссылке).
С точки зрения конкретного примера, показанного выше, EHLLAPI от IBM является довольно непротиворечивым интерфейсом.
Все вызовы проходят четыре пустых указателя (EHLLAPI отправляет код возврата через четвертый параметр, указатель на int
так что пока уточняю int
как тип возврата, я могу смело его игнорировать) согласно документации IBM здесь. Другими словами, вариант C функции будет:
int hllApi (void *p1, void *p2, void *p3, void *p4)
Это делает для одного, простого ctypes
Функция может делать все, что предоставляет библиотека EHLLAPI, но, вероятно, другим библиотекам потребуется отдельное ctypes
функция устанавливается для библиотечной функции.
Возвращаемое значение из WINFUNCTYPE
является прототипом функции, но вам все равно нужно настроить больше информации о параметрах (помимо типов). Каждый кортеж в hllApiParams
имеет параметр "direction" (1 = вход, 2 = выход и т. д.), имя параметра и значение по умолчанию - см. ctypes
доку для деталей
Когда у вас есть прототип и информация о параметрах, вы можете создать Python "вызываемый" hllApi
с помощью которого вызывать функцию. Вы просто создаете необходимую переменную (p1
через p4
в моем случае) и вызовите функцию с ними.
На этой странице приведен очень простой пример вызова функций из DLL-файла.
Перефразируя детали здесь для полноты:
В Python очень легко вызвать функцию DLL. У меня есть самодельный файл DLL с двумя функциями:
add
а такжеsub
которые принимают два аргумента.
add(a, b)
возвращает сложение двух чиселsub(a, b)
возвращает вычитание двух чиселИмя файла DLL будет "demo.dll"
Программа:
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
Выход:
Addition value:11
Substraction:9
Сборка DLL и связывание ее под Python с использованием ctypes
Я представляю полностью проработанный пример того, как построить shared library
и используя его под Python
посредством ctypes
, Я считаю Windows
дело и дело с DLLs
, Требуются два шага:
- Сборка DLL с использованием компилятора Visual Studio либо из командной строки, либо из IDE;
- Свяжите DLL под Python, используя ctypes.
Общая библиотека
shared library
Я считаю, что это следующее и содержится в testDLL.cpp
файл. Единственная функция testDLL
просто получает int
и печатает это.
#include <stdio.h>
extern "C" {
__declspec(dllexport)
void testDLL(const int i) {
printf("%d\n", i);
}
} // extern "C"
Сборка DLL из командной строки
Чтобы построить DLL
с Visual Studio
из командной строки запустить
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\vsdevcmd"
установить путь включения, а затем запустить
cl.exe /D_USRDLL /D_WINDLL testDLL.cpp /MT /link /DLL /OUT:testDLL.dll
построить DLL.
Строительство DLL
из IDE
В качестве альтернативы DLL
можно построить с помощью Visual Studio
следующее:
- Файл -> Новый -> Проект;
- Установлено -> Шаблоны -> Visual C++ -> Windows -> Win32 -> Win32Project;
- Следующий;
- Тип приложения -> DLL;
- Дополнительные опции -> Пустой проект (выбрать);
- Дополнительные параметры -> Предварительно скомпилированный заголовок (отменить выбор);
- Проект -> Свойства -> Диспетчер конфигурации -> Платформа активного решения: x64;
- Проект -> Свойства -> Диспетчер конфигурации -> Активная конфигурация решения: Выпуск.
Связывание DLL под Python
Под Python сделайте следующее
import os
import sys
from ctypes import *
lib = cdll.LoadLibrary('testDLL.dll')
lib.testDLL(3)
ctypes можно использовать для доступа к dll, вот учебник:
Может быть с Dispatch
:
from win32com.client import Dispatch
zk = Dispatch("zkemkeeper.ZKEM")
Где zkemkeeper - это зарегистрированный файл DLL в системе... После этого вы можете получить доступ к функциям, просто вызвав их:
zk.Connect_Net(IP_address, port)
ctypes будет проще всего использовать, но (неправильное) его использование делает Python подверженным сбоям. Если вы пытаетесь что-то сделать быстро и осторожны, это здорово.
Я бы посоветовал вам проверить Boost Python. Да, это требует, чтобы вы написали некоторый код C++ и имели компилятор C++, но на самом деле вам не нужно изучать C++ для его использования, и вы можете получить бесплатный (как в пиве) компилятор C++ от Microsoft.
Если DLL имеет тип библиотеки COM, вы можете использовать pythonnet.
pip install pythonnet
Затем в вашем коде Python попробуйте следующее
import clr
clr.AddReference('path_to_your_dll')
затем создайте экземпляр объекта в соответствии с классом в DLL и получите доступ к его методам.