8-900-374-94-44
[email protected]
Slide Image
Меню

Python dll: DLL & Python / Хабр

Python. Вызов функции DLL со строковыми параметрами

    Вот я добрался и до Python. Так сказать – первые пробы пера. Но куда я в Python без Delphi? Сегодня столкнулся с тем, что в Python нужно было вызвать функцию из DLL, которая была написана много лет тому назад на Delphi.
    Немного общей теории. Для вызова функций из сторонних библиотек в Python есть специальный модуль — ctypes. Этот модуль предоставляет разработчику C-совместимые типы данных и позволяет вызывать функции под различными операционными системами. Для загрузки динамических библиотек модуль ctypes предоставляет три метода:

  • cdll — загружает библиотеки, которые экспортируют функции используя соглашение о вызовах cdecl;
  • windll — загружает библиотеки, которые экспортируют функции используя соглашение о вызовах stdcall;
  • oledll — загружает библиотеки, которые экспортируют функции используя соглашение о вызовах stdcall и предполагает, что результат функции имеет тип HRESULT (как это требуют COM/OLE).

Итак, у нас есть DLL работающая со строками:

library xyz;
function TestW(const pText1, pText2: PChar): PChar; stdcall;
begin
  Result := ...;
end;
function TestA(const pText1, pText2: PAnsiChar): PAnsiChar; stdcall;
begin
  Result := ...;
end;
exports
  TestA, TestW;
begin
end.

Как вы видите, DLL экспортируют функции используя соглашение о вызовах stdcall, поэтому загружаем ее с помощью метода windll:

import ctypes
text1 = 'Привет'
text2 = 'Delphi'
# загружаем DLL
lib  = ctypes.WinDLL('xyz.dll')
# получаем функцию
funcTest = lib.TestW
# задаем типы параметров функции
funcTest.argtypes = ctypes.c_wchar_p, ctypes.c_wchar_p
# задаем тип результата функции
funcTest.restype = ctypes.c_wchar_p
# вызываем функцию и выводим результат ее выполнения
print(funcTest(text1, text2))

    Вызов функции с параметрами типа PAnsiChar немного сложнее:

import ctypes
text1 = 'Привет'
text2 = 'Delphi'
lib  = ctypes. WinDLL('xyz.dll')
funcTest = lib.TestA
funcTest.restype = ctypes.c_char_p
funcTest.argtypes = ctypes.c_char_p, ctypes.c_char_p
print(funcTest(text1.encode(), text2.encode()).decode())

Как вы видите, кроме изменения типа параметров, в коде появились вызовы методов encode() и decode(). Метод encode() кодирует параметры в байтовые строки. Если это не сделать, то во время выполнения программы мы получим ошибку:

ctypes.ArgumentError: argument 1: : wrong type

Метод decode() выполняет обратную операцию – он декодирует результат выполнения функции из байтовой строки. Если это не сделать, то print, при выводе результата функции, вместо русских букв выведет байты. Например, строка «Привет Python» превратится в «b’\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82 Python'».

    Даже для меня, человека, который плохо знает Python, вызвать функцию из DLL оказалось очень легко.

Загрузка dll с использованием Python Ctypes

Я рассмотрел приведенный здесь пример ctypes — Beginner и выполнил те же шаги с другим фрагментом кода C. Я создал .dll и .lib, используя приведенный здесь код C: http://wolfprojects.altervista.org/articles/dll-in-c-for-python/

//test.c
__declspec(dllexport) int sum(int a, int b) {
    вернуть а + б;
}
 

В моем файле wrapper.py есть это:

 import ctypes
testlib = ctypes.CDLL("C:\\Users\\xyz\\Documents\\Python\\test.dll")
 

Когда я запускаю скрипт, я получаю эту ошибку:

self._handle = _dlopen(self._name, режим)

OSError: [WinError 193] %1 не является допустимым приложением Win32

Если я использую

 testlib = ctypes.LibraryLoader("C:\\Users\\xyz\\Documents\\Python\\test.dll")
 

, тогда я не получаю никаких ошибок при запуске скрипта. Но если я попытаюсь сделать это:

 testlib.sum(3,4)
 

Я получаю сообщение об ошибке:

dll = self._dlltype(имя)

TypeError: объект ‘str’ не может быть вызван

DLL и . py находятся в одной папке. Может ли кто-нибудь помочь мне понять, что здесь происходит. Я потратил часы, пытаясь понять это, но наткнулся на стену. Спасибо.

  • питон
  • ctypes

1

Убедитесь, что ваш компилятор и версия Python являются 32-разрядными или 64-разрядными. Вы не можете смешивать, что является причиной OSError: [WinError 193] %1 не является допустимым приложением Win32 .

Затем убедитесь, что программа компилируется как программа на C, а не на C++. Это причина упоминания искажения имени в вашем ответе.

Пример (примечание компилятор для x86 не x64 :

 C:\>cl /LD /W4 test.c
Оптимизирующий компилятор Microsoft (R) C/C++ версии 17.00.61030 для x86
Авторское право (C) Microsoft Corporation. Все права защищены.
тест.с
Инкрементальный компоновщик Microsoft (R) версии 11.00.61030.0
Авторское право (C) Microsoft Corporation.  Все права защищены.
/out:test.dll
/dll
/implib:test.lib
тест.obj
   Создание библиотеки test.lib и объекта test.exp
 

Теперь используйте 32-битный Python:

 C:\>py -2
Python 2.7.13 (v2.7.13:a06454b1afa1, 17 декабря 2016 г., 20:42:59) [MSC v.1500 32 бит (Intel)] на win32
Введите «помощь», «авторское право», «кредиты» или «лицензия» для получения дополнительной информации.
>>> из импорта ctypes *
>>> lib = CDLL('тест')
>>> lib.sum(2, 3)
5
 

Если вы компилируете как C++, вы все равно можете вызывать функции, экспортируя их как C, что предотвращает искажение имени C++:

test.cpp

 внешний "C" __declspec(dllexport) int sum(int a, int b) {
    вернуть а + б;
}
 

3

После дальнейших поисков я нашел решение. Компилятор C исказил имя функции, поэтому я получил ошибку атрибута при вызове метода суммы. Мне пришлось использовать link.exe, чтобы выяснить искаженное имя, а затем использовать метод getattr .

Подробнее и объяснение в этом посте: Python: доступ к функции DLL с использованием ctypes — доступ по функции *имя* не работает

1

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя электронную почту и пароль

Опубликовать как гость

Электронная почта

Требуется, но никогда не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

python.

dll скачать бесплатно | DLL‑files.com python.dll скачать бесплатно | DLL‑files.com

DLL‑files.com На сайте с 1998 г.
реклама

Загрузите python.dll ниже, чтобы решить вашу проблему с dll. В настоящее время у нас есть 1 версия для этого файла.

Если у вас есть другие версии этого файла, внесите свой вклад в сообщество, загрузив этот DLL-файл.

Ошибки, связанные с python.dll, могут возникать по нескольким причинам. Например, ошибочное приложение: python.dll было удалено или потеряно, повреждено вредоносным программным обеспечением, присутствующим на вашем компьютере, или поврежден реестр Windows.

Наиболее часто встречающиеся сообщения об ошибках:

  • Запуск программы невозможен, так как на вашем компьютере отсутствует python. dll. Попробуйте переустановить программу, чтобы решить эту проблему.
  • Возникла проблема при запуске python.dll. Указанный модуль не может быть найден.
  • Ошибка загрузки python.dll. Указанный модуль не может быть найден.
  • Невозможно продолжить выполнение кода, так как не найден файл python.dll. Переустановка программы может решить эту проблему.
  • python.dll либо не предназначен для работы в Windows, либо содержит ошибку. Попробуйте установить программу еще раз, используя исходный установочный носитель, или обратитесь за поддержкой к системному администратору или поставщику программного обеспечения.

В подавляющем большинстве случаев решение состоит в правильной переустановке python.dll на вашем компьютере в системную папку Windows. В качестве альтернативы, некоторые программы, особенно игры для ПК, требуют, чтобы файл DLL был помещен в папку установки игры/приложения.

Подробные инструкции по установке см.

в разделе часто задаваемых вопросов.

реклама

Версия

Архитектура

Размер файла

Язык

Компания

Описание

0.0.0.0

32

0,11 МБ

Неизвестно

.

MD5: