Уведомления

Группа в Telegram: @pythonsu

#1 Март 23, 2009 17:21:15

Bahus
От:
Зарегистрирован: 2009-03-23
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Включение собственных dll в exe с последующим вызовом функций из них

Привет всем.

Собираю экзешник для своего скрипта, используя py2exe.
Возникла следующая проблема:

есть у меня длл-ка, которую необходимо включить в собранный файл и использовать функции из неё, причем не распаковывая эту длл на жесткий диск. Т.е. нужно провернуть 3 действия в следующем порядке:

1. Добавить длл в exe как ресурс при сборке
2. Во время запуска exe загрузить длл из ресурсов в адресное пространство процесса и получить её handle
3. Передать полученный handle в функцию ctypes.WinDLL

Что мне удалось нарыть по каждому из “действий”:

1. Собственно это можно сделать, чем угодно. Например я сделал так:

autoitlib = open(".\AutoItX3.dll", "rb").read()
setup(
console = [{"script":"test.py", "other_resources":[(u"AUTOITX3.DLL", 1, autoitlib)]}],
)
Вот подтверждения из ресхакера:



2-3. Здесь заюзать ctype.LoadLibrary невозможно, т.к. она принимает только имя файла, поэтому придется использовать WinAPI как описано здесь:
http://www.py2exe.org/index.cgi/CustomDataInExe

В итоге имеем следующий скрипт для компиляции:

from ctypes import *

def GetModuleHandle(filename=None):
h=windll.kernel32.GetModuleHandleW(filename)
if not h:
raise WinError()
return h

def FindResource(typersc,idrsc,c_restype=c_char,filename=None):
if type(idrsc)is int:
idrsc='#%d'%idrsc
if type(typersc) is int:
typersc='#%d'%typersc
hmod=GetModuleHandle(filename)
print(hmod)
hrsc=windll.kernel32.FindResourceW(hmod,typersc,idrsc)
if not hrsc:
raise "111:" + str(WinError())
hglobal=windll.kernel32.LoadResource(hmod,hrsc)
if not hglobal:
raise WinError()
windll.kernel32.LockResource.restype=POINTER(c_restype)
return windll.kernel32.LockResource(hglobal)[0]

if __name__ == "__main__":

libhandle = FindResource(u"AUTOITX3.DLL", 1)
AutoIt = WinDLL(u"AUTOITX3.DLL", handle = libhandle)
Проблема в том, что при запуске получившегося exe файла получаю эксепшен:

111:[Error 1813] The specified resource type cannot be found in the image file."
на строчке

hrsc=windll.kernel32.FindResourceW(hmod,typersc,idrsc)
Вопрос: что я делаю не так? :)

P.S. Прикол в том, что нужный мне код есть в py2exe_util.pyd в функции load_resources, но по понятным причинам он не доступен.



Отредактировано (Март 23, 2009 17:22:11)

Офлайн

#2 Март 24, 2009 09:45:55

Bahus
От:
Зарегистрирован: 2009-03-23
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Включение собственных dll в exe с последующим вызовом функций из них

Ладно, вопрос снят.

Код py2exe_util.с был найдет в SVN - http://py2exe.svn.sourceforge.net/viewvc/py2exe/tags/release_0_6_9/source/py2exe_util.c?revision=681&view=markup

Функция load_resources оттуда позволяет получить бинарные данные самой дллки либо указатель на них в памяти, но эту информацию нельзя использовать для инициализации функций из этой длл :(

Максимум что можно сделать, это сохранить полученную инфу в файл, и уже загружать его в память как длл, а чтобы загрузить длл непосредственно из ресурсов необходимо писать свой PE загрузчик, как написано здесь http://www.rsdn.ru/article/baseserv/peloader.xml



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version