Автор Тема: Запуск .dll из Python  (Прочитано 6284 раз)

Оффлайн Samovar

  • Житель
Запуск .dll из Python
« : 27 Ноябрь 2016, 12:23:34 »

Хотя, конечно, правильней  вопрос будет звучать как "обращение к функциям .dll из Python".
Это возможно? Если да, то как?

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: Запуск .dll из Python
« Ответ #1 : 27 Ноябрь 2016, 13:34:54 »
Если это просто левая, никак не связанная с системой DLL, то, скорее всего, без написания расширения на C не обойтись.

Если же это зарегистрированный в винде COM-объект, то в Питоне есть модуль для работы с такими объектами.
Я делал это так:
Код
from win32com.client import Dispatch
try:
    comobj=Dispatch("Super_puperDLL.ComObject")
except:
    print ("COM-объект не найден")
    sys.exit(1)
где вместо "Super_puperDLL.ComObject" ставишь правильное название COM-объекта. Все существующие COM-объекты в винде можно посмотреть, например, в Excel, точнее, в его VisualBasic-редакторе, скорее всего в какой-нибудь VisualStudio тоже можно.

Далее пользуешься методами объекта в переменной comobj. Имена и аргументы этих методов разные и зависят от DLL.

Оффлайн Samovar

  • Житель
Re: Запуск .dll из Python
« Ответ #2 : 27 Ноябрь 2016, 15:59:58 »
Спасибо за ответ, но речь не про COM, а про обычные .dll ( .so, если не ошибаюсь, в Юниксах). Так как Python великий тормоз, проще написать функции на каком либо реальном ЯП и скомпилировать в .dll, но встаёт вопрос как из Python вызывать эти функции, и можно ли вообще?
« Последнее редактирование: 27 Ноябрь 2016, 16:17:52 от Samovar »

Оффлайн LanuHum

  • Житель
Re: Запуск .dll из Python
« Ответ #3 : 27 Ноябрь 2016, 18:02:25 »
Спасибо за ответ, но речь не про COM, а про обычные .dll ( .so, если не ошибаюсь, в Юниксах). Так как Python великий тормоз, проще написать функции на каком либо реальном ЯП и скомпилировать в .dll, но встаёт вопрос как из Python вызывать эти функции, и можно ли вообще?
Самое простое использование ctypes:
https://docs.python.org/3.5/library/ctypes.html#module-ctypes
>>> from ctypes import *
>>> print(windll.kernel32) 
<WinDLL 'kernel32', handle ... at ...>
>>> print(cdll.msvcrt)     
<CDLL 'msvcrt', handle ... at ...>
>>> libc = cdll.msvcrt     
Другой вариант здесь:
http://blender-3d.ru/forum/index.php/topic,1529.0.html
Третий вариант здесь:
https://docs.python.org/3/extending/extending.html
Четвёртый вариант:
https://ru.wikipedia.org/wiki/SWIG
Пятый вариант:
https://habrahabr.ru/post/168083/

Оффлайн LanuHum

  • Житель
Re: Запуск .dll из Python
« Ответ #4 : 27 Ноябрь 2016, 18:24:25 »
К моему предыдущему посту.
Вот здесь что-то про FreeBasic, Python, ctypes:
http://www.freebasic.net/forum/viewtopic.php?t=3946

Оффлайн Samovar

  • Житель
Re: Запуск .dll из Python
« Ответ #5 : 28 Ноябрь 2016, 15:19:08 »
Спасибо за ответ, но речь не про COM, а про обычные .dll ( .so, если не ошибаюсь, в Юниксах). Так как Python великий тормоз, проще написать функции на каком либо реальном ЯП и скомпилировать в .dll, но встаёт вопрос как из Python вызывать эти функции, и можно ли вообще?
Самое простое использование ctypes:
https://docs.python.org/3.5/library/ctypes.html#module-ctypes
>>> from ctypes import *
>>> print(windll.kernel32) 
<WinDLL 'kernel32', handle ... at ...>
>>> print(cdll.msvcrt)     
<CDLL 'msvcrt', handle ... at ...>
>>> libc = cdll.msvcrt     
Другой вариант здесь:
http://blender-3d.ru/forum/index.php/topic,1529.0.html
Третий вариант здесь:
https://docs.python.org/3/extending/extending.html
Четвёртый вариант:
https://ru.wikipedia.org/wiki/SWIG
Пятый вариант:
https://habrahabr.ru/post/168083/
Спасибо Ланухумыч!

Оффлайн Samovar

  • Житель
Re: Запуск .dll из Python
« Ответ #6 : 28 Ноябрь 2016, 15:20:22 »
К моему предыдущему посту.
Вот здесь что-то про FreeBasic, Python, ctypes:
http://www.freebasic.net/forum/viewtopic.php?t=3946
А за это спасибо вдвойне! Это то, что нужно! Буду пробовать.

Оффлайн LanuHum

  • Житель
Re: Запуск .dll из Python
« Ответ #7 : 11 Декабрь 2016, 14:39:20 »
А за это спасибо вдвойне! Это то, что нужно! Буду пробовать.

Как выяснилось, ctypes ускоряет работу программы ни на столько насколько хотелось бы.
Это худший вариант.

 Лучший вариант, как мне показалось, писать на С++ используя boost-python. Но, как сейчас убедился, с третьим питоном проблема:
ImportError: /home/leonid/workspace/programming/python_c++/extend/simpleExample.cpython-34m.so: undefined symbol: _ZN5boost6python6detail11init_moduleER11PyModuleDefPFvvE
Больше всего пользуют, именно, boost и, меньше всего python3, ибо ответы на вопросы пользователей "какого ляда символ не объявлен?" выглядят неадекватно. Так что, если писать модули для использования в Блендере, используя boost, можно зря потратить нервы.

SWIG потребует кроме изучения С\С++ ещё и изучение написания интерфейсных файлов, про которые на русском написано только про Hello World! Да, именно на русском написано, как питоном вызвать сишную функцию выводящую в терминал(смд) "Hello, World!"
Очень нужная информация, герои те, кто нам её предоставил. Важнее нет ничего, кроме как таким способом в консоли писать два слова.

Cython, тоже, вижу, не популярен, но разобраться можно, если не потребуется включения сторонних библиотек. Я не смог создать текстовой файл. Пишет бинарник, и ноль информации на просторах инета про написание текстовых файлов ситоном. Зато с обычной арифметикой тут удобно и можно отрубать блокировку питоном многопоточности.

Всей этой хрени можно бы было избежать, если бы я хоть где-то нашёл пример написания кода питонового модуля на С, который можно собрать обычной командой g++. Даже, "Хелоу, мир!" не нашёл. То setuptools нужно, то distutils, то ещё фигню какую-то.

Оффлайн LanuHum

  • Житель
Re: Запуск .dll из Python
« Ответ #8 : 11 Декабрь 2016, 21:51:19 »
Ага, разобрался с boost-python3. Невнимательно посмотрел. Есть пакет, но был не установлен.
Пример нашёл в интернете коротенький. Файл greet_binding.cpp:
Код
#include <iostream>
#include <boost/python/def.hpp>
#include <boost/python/module.hpp>
using namespace std;
namespace bp = boost::python;
void say_greeting(const char* name)
{
cout << "Hello, " << name << "!\n";
}
BOOST_PYTHON_MODULE(greet)
{
bp::def("say_greeting", say_greeting);
}
Перейдя в каталог с файлом нужно собрать его командой (линукс):
Код
g++ greet_binding.cpp -I/usr/include/python3.4m -lboost_python3 -lpython3.4m -o greet.so -shared -fPIC
Теперь в каталоге появился файл greet.so. Здесь же размещаем файл test.py с текстом:
Код
import greet
a = greet.say_greeting("Eric")
print (a)
Запускаем файл из консоли, читаем в консоли:
Hello, Eric!
None

Хоть это и примитивный Hello World, но он показывает все задействованные механизмы создания библиотеки на плюсах как модуля для питона.
Разумеется, это подходит для случаев самописного модуля в виде .so или .dll. Если бинарник уже кем-то создан, то ctypes.
Кстати, с кириллицей проблем нет в линуксе при использовании boost.
« Последнее редактирование: 11 Декабрь 2016, 22:52:54 от LanuHum »

Оффлайн Samovar

  • Житель
Re: Запуск .dll из Python
« Ответ #9 : 14 Декабрь 2016, 17:27:31 »
Ланухумыч, меня интересует прежде всего вариант ctypes. Попробовал на IDE Python 2.6.2 врубать скомпилированную на FB либу... работает (правда с кодировками видимо проблема...но это ничего)... Пробовал из Blender'a тоже самое...нихрена не работает... как в 2.49 так и в 2.78... ругается постоянно...
Вбил в интерактивной консоли Блендера >>>help ('_ctypes')
выдало дохрена инфы... и не пнонял почему эта команда (модуль... я особо не шарю) начинается с подчёркивания в Блендере?..
Если можешь, пришли рабочий пример скрипта, пожалуйста, а dll-ку я сам соберу.

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: Запуск .dll из Python
« Ответ #10 : 14 Декабрь 2016, 18:36:58 »
Цитировать
и не пнонял почему эта команда (модуль... я особо не шарю) начинается с подчёркивания в Блендере?..
ctypes - пакет модулей, написанных на питоне (находится в blender-2.78-windows64\2.78\python\lib\ctypes\*)
_ctypes - связанный с этим пакетом бинарный файл blender-2.78-windows64\2.78\python\lib\_ctypes.pyd )
импортировать надо пакет ctypes, а бинарник он сам должен подтянуть.

Цитировать
нихрена не работает... как в 2.49 так и в 2.78... ругается постоянно...
чо конкретно пишет?

Оффлайн Samovar

  • Житель
Re: Запуск .dll из Python
« Ответ #11 : 14 Декабрь 2016, 18:44:30 »

dll на FB

Код

' This function adds two numbers (i've taken it from Freebasic manuel !)
Function AddNumbers CDECL Alias "AddNumbers" ( ByVal operand1 As Integer, ByVal operand2 As Integer) As Integer Export
   AddNumbers = operand1 + operand2
End Function         


' This one shows uppercase text
Function ShowText CDECL Alias "ShowText" (ByVal MyText As String)  As Integer Export     
   Print ucase(Mytext)
   Return 1
End Function
Python
Код
#__ LOAD MODULE CTYPE __
from ctypes import *


#__ LOAD THE DLL __
libFreeBasic = cdll.LoadLibrary("mydll.dll")


#__ CALL FUNCION WITH INTEGER PARAMETER __
print (libFreeBasic.AddNumbers(5,7))


#__ CALL FUNCTION WITH STRING PARAMETER AND GET RETURN CODE__
s_MyText = "Hello"
c_MyText = c_char_p(s_MyText)
RetCode = libFreeBasic.ShowText(s_MyText)


RetMsg = "Return code : " + str(RetCode)
print (RetMsg)
Цитировать



Traceback (most recent call last):
  File "C:\Users\Den\Desktop\FB\testdll.blend\Text", line 5, in <module>
  File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\ctypes\__ini
t__.py", line 425, in LoadLibrary
    return self._dlltype(name)
  File "C:\Program Files\Blender Foundation\Blender\2.78\python\lib\ctypes\__ini
t__.py", line 347, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 126] Не найден указанный модуль
Error: Python script fail, look in the console for now...

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: Запуск .dll из Python
« Ответ #12 : 14 Декабрь 2016, 19:05:59 »
Цитировать
OSError: [WinError 126] Не найден указанный модуль
В Notepad++ перевёл в UTF8 эту хрень:
РќРµ найден указанный модуль = Не найден указанный модуль
Т.е. он не находит твою dll-ку.

Скинь её сюда (неохота у себя Basic ставить), попробую из Блендера подключиться.

Оффлайн Samovar

  • Житель
Re: Запуск .dll из Python
« Ответ #13 : 14 Декабрь 2016, 19:13:33 »
Вот малёха переделанная для x64... должна окно 400х400 нарисовать...


Код
' This function adds two numbers (i've taken it from Freebasic manuel !)
Function AddNumbers CDECL Alias "AddNumbers" ( ByVal operand1 As Integer, ByVal operand2 As Integer) As Integer Export
   AddNumbers = operand1 + operand2
End Function         


' This one shows uppercase text
Function ShowText CDECL Alias "ShowText" (ByVal MyText As String)  As Integer Export     
   'Print ucase(Mytext)
   ScreenRes 400,400
   Return 1
End Function

Оффлайн Striver

  • Житель
  • недоинженер, полупрограммист
    • http://striver00.ru
Re: Запуск .dll из Python
« Ответ #14 : 14 Декабрь 2016, 19:29:21 »
вписал полный путь, модуль проимпортировался:
Код
>>> #__ LOAD THE DLL __
>>> libFreeBasic = cdll.LoadLibrary("mydll.dll")
Traceback (most recent call last):
  File "<blender_console>", line 1, in <module>
  File "I:\Programs64\Blender\blender-2.78-windows64\2.78\python\lib\ctypes\__init__.py", line 425, in LoadLibrary
    return self._dlltype(name)
  File "I:\Programs64\Blender\blender-2.78-windows64\2.78\python\lib\ctypes\__init__.py", line 347, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 126] Не найден указанный модуль

>>> libFreeBasic = cdll.LoadLibrary(r"D:\moe\blender\Vopros\mydll.dll")
>>> print (libFreeBasic.AddNumbers(5,7))
12

на функцию ShowText появилось окошко.

 


Яметрика

* По форуму

* Рекламный блок

* Последние вложения

1 (1).png
Скачано: 64
Автор: LEXA ANЭGROWND
blender.png
Скачано: 74
Автор: ipv2007
4.png
Скачано: 96
Автор: hiroyukiss
2.png
Скачано: 119
Автор: hiroyukiss

Скачано: 109
Автор: Dilifa12