Как я могу использовать файл DLL из Python? - PullRequest
165 голосов
/ 31 октября 2008

Какой самый простой способ использовать файл DLL из Python?

В частности, как это можно сделать без записи какого-либо дополнительного кода оболочки C++ для предоставления функциональности Python?

Собственная функциональность Python настоятельно рекомендуется использовать стороннюю библиотеку.

Ответы [ 6 ]

139 голосов
/ 31 октября 2008

Для простоты использования, 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) и вызываете функцию с ними.

59 голосов
/ 04 июля 2010

Эта страница содержит очень простой пример вызова функций из 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

7 голосов
/ 31 октября 2008

ctypes можно использовать для доступа к DLL, вот учебник:

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

5 голосов
/ 18 июня 2013

Может быть с Dispatch:

from win32com.client import Dispatch

zk = Dispatch("zkemkeeper.ZKEM") 

Где zkemkeeper - зарегистрированный файл DLL в системе ... После этого вы можете получить доступ к функциям, просто вызвав их:

zk.Connect_Net(IP_address, port)
3 голосов
/ 31 октября 2008

ctypes будет проще всего использовать, но (неправильное) использование делает Python подверженным сбоям. Если вы пытаетесь что-то сделать быстро и осторожны, это здорово.

Я бы посоветовал вам проверить Boost Python . Да, это требует, чтобы вы написали некоторый код C ++ и имели компилятор C ++, но на самом деле вам не нужно изучать C ++ для его использования, и вы можете получить бесплатный (как в пиве) компилятор C ++ от Microsoft .

0 голосов
/ 04 апреля 2019

Сборка DLL и связывание ее под Python с использованием ctypes

Я представляю полностью проработанный пример того, как построить shared library и использовать его в Python с помощью ctypes. Я рассматриваю дело Windows и имею дело с DLLs. Необходимы два шага:

  1. Сборка DLL с использованием компилятора Visual Studio либо из командной строки, либо из IDE;
  2. Свяжите 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 из ИДЭ

В качестве альтернативы DLL можно построить с помощью Visual Studio следующим образом:

  1. Файл -> Новый -> Проект;
  2. Установлено -> Шаблоны -> Visual C ++ -> Windows -> Win32 -> Win32Project;
  3. Далее;
  4. Тип приложения -> DLL;
  5. Дополнительные опции -> Пустой проект (выбрать);
  6. Дополнительные опции -> Предварительно скомпилированный заголовок (отменить выбор);
  7. Проект -> Свойства -> Диспетчер конфигурации -> Платформа активного решения: x64;
  8. Проект -> Свойства -> Диспетчер конфигурации -> Активная конфигурация решения: выпуск.

Связывание DLL под Python

Под Python выполните следующее

import os
import sys
from ctypes import *

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

lib.testDLL(3)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...