I need to load the dll from the resource, so I use Class _MemoryLibrary, Class _Struct and sizeof(), and the whole script is pretty large. The uncompiled script works (I read the dll using File.RawRead()), but the compiled script (dll is added to resource using @Ahk2Exe-AddResource) produces the error:
What may be the issue?
AHK_H v1.1.33.2 Compiled file doesn't handle the large script
-
- Posts: 4326
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: AHK_H v1.1.33.2 Compiled file doesn't handle the large script
Why don't you use AhkThread?
How do you read the dll from resource? The error must be here!
How do you read the dll from resource? The error must be here!
-
- Posts: 4326
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: AHK_H v1.1.33.2 Compiled file doesn't handle the large script
The dll is not AutoHotkey.dll.
Code: Select all
ExtractResource(filePath, resourceName, ByRef buff)
{
static LOAD_LIBRARY_AS_DATAFILE := 0x00000002, RT_RCDATA := "#10"
if (filePath = "")
hMod := 0
else if !hMod := DllCall("LoadLibraryEx", "Str", filePath, "Ptr", 0, "UInt", LOAD_LIBRARY_AS_DATAFILE, "Ptr")
throw "Failed to load file"
if !hRes := DllCall("FindResource", "Ptr", hMod, "Str", resourceName, "Str", RT_RCDATA, "Ptr")
throw "FindResource failed, error: " . A_LastError
hData := DllCall("LoadResource", "Ptr", hMod, "Ptr", hRes, "Ptr")
szData := DllCall("SizeofResource", "Ptr", hMod, "Ptr", hRes)
pData := DllCall("LockResource", "Ptr", hData, "Ptr")
VarSetCapacity(buff, szData, 0)
DllCall("RtlMoveMemory", "Ptr", &buff, "Ptr", pData, "Ptr", szData)
DllCall("FreeLibrary", "Ptr", hMod)
Return szData
}
My script:
Code: Select all
;@Ahk2Exe-AddResource zlib1.dll
#NoEnv
SetBatchLines, -1
#Include <_MemoryLibrary>
; #Include D:\Downloads\ahkdll-v1-release-master\Compiler\Lib\ResGet.ahk
size := CreateScreenshot(50, buff)
len := GetZlibBuff(zlib)
; ensure the extraction is correct
File := FileOpen(A_ScriptDir . "\zlib_from_resource.dll", "w")
File.RawWrite(zlib, len)
File.Close()
size := CompressData(&buff, size, compressed, &zlib)
VarSetCapacity(buff, 0), buff := ""
File := FileOpen(A_ScriptDir . "\compressed.jpg", "w", "cp0")
File.RawWrite(compressed, size)
File.Close()
VarSetCapacity(compressed, 0), compressed := ""
ExitApp
GetZlibBuff(ByRef zlib) {
if A_IsCompiled
len := ExtractResource("", "ZLIB1.DLL", zlib)
; len := ResGet(zlib, A_AhkPath, "ZLIB1.DLL")
else {
File := FileOpen("zlib1.dll", "r")
len := File.RawRead(zlib, File.Length)
File.Close()
if !len
throw "Failed to read dll"
}
Return len
}
CompressData(pData, dataSize, ByRef outData, pZLib, compress := true) {
ZL := new ZlibCompression(pZLib)
size := ZL.Compression(pData, dataSize, outData, "deflate")
Return size
}
ExtractResource(filePath, resourceName, ByRef buff)
{
static LOAD_LIBRARY_AS_DATAFILE := 0x00000002, RT_RCDATA := "#10"
if (filePath = "")
hMod := 0
else if !hMod := DllCall("LoadLibraryEx", "Str", filePath, "Ptr", 0, "UInt", LOAD_LIBRARY_AS_DATAFILE, "Ptr")
throw "Failed to load file"
if !hRes := DllCall("FindResource", "Ptr", hMod, "Str", resourceName, "Str", RT_RCDATA, "Ptr")
throw "FindResource failed, error: " . A_LastError
hData := DllCall("LoadResource", "Ptr", hMod, "Ptr", hRes, "Ptr")
szData := DllCall("SizeofResource", "Ptr", hMod, "Ptr", hRes)
pData := DllCall("LockResource", "Ptr", hData, "Ptr")
VarSetCapacity(buff, szData, 0)
DllCall("RtlMoveMemory", "Ptr", &buff, "Ptr", pData, "Ptr", szData)
DllCall("FreeLibrary", "Ptr", hMod)
Return szData
}
CreateScreenshot(jpgQuality, ByRef buff) {
hBitmap := HBitmapFromScreen(0, 0, A_ScreenWidth, A_ScreenHeight)
Gdip := new GDIplus
pBitmap := Gdip.CreateBitmapFromHBITMAP(hBitmap)
size := Gdip.SaveBitmap(pBitmap, buff := "jpg", jpgQuality, true)
DllCall("DeleteObject", "Ptr", hBitmap)
Gdip.DisposeImage(pBitmap)
Return size
}
HBitmapFromScreen(X, Y, W, H) {
static SRCCOPY := 0x00CC0020
HDC := DllCall("GetDC", "Ptr", 0, "UPtr")
HBM := DllCall("CreateCompatibleBitmap", "Ptr", HDC, "Int", W, "Int", H, "UPtr")
PDC := DllCall("CreateCompatibleDC", "Ptr", HDC, "UPtr")
DllCall("SelectObject", "Ptr", PDC, "Ptr", HBM)
DllCall("BitBlt", "Ptr", PDC, "Int", 0, "Int", 0, "Int", W, "Int", H
, "Ptr", HDC, "Int", X, "Int", Y, "UInt", SRCCOPY)
DllCall("DeleteDC", "Ptr", PDC)
DllCall("ReleaseDC", "Ptr", 0, "Ptr", HDC)
Return HBM
}
class ZlibCompression
{
/*
https://www.zlib.net/manual.html
http://refspecs.linuxbase.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/zlib-deflateinit2.html
http://refspecs.linuxbase.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/zlib-inflateinit2.html
*/
__New(pZlib) {
this.zlib := new _MemoryLibrary(pZlib)
}
__Delete() {
if (this.zlib.MM.init = 1)
this.zlib.Free()
}
Compression(pData, length, ByRef out, action) ; actions: compress — "deflate" or true
{ ; decompress — "inflate" or false
static MAX_MEM_LEVEL := 9, Z_DEFLATED := 8, Z_DEFAULT_STRATEGY := 0
, MAX_WBITS := 15, Z_OK := 0, Z_FINISH := 4, Z_STREAM_END := 1
, errors := [ "Z_ERRNO" , "Z_STREAM_ERROR", "Z_DATA_ERROR"
, "Z_MEM_ERROR", "Z_BUF_ERROR" , "Z_VERSION_ERROR" ]
, level := 9
b := action ~= "i)1|de"
VarSetCapacity(out, outMaxLen := length*(b ? 2 : 20), 0)
VarSetCapacity(z_stream_s, szStream := 24 + 8*A_PtrSize, 0)
NumPut(pData , z_stream_s)
NumPut(length , z_stream_s, A_PtrSize, "UInt")
NumPut(&out , z_stream_s, A_PtrSize + 8)
NumPut(outMaxLen, z_stream_s, A_PtrSize + 8 + A_PtrSize, "UInt")
params := ["Int", 16 + MAX_WBITS, "AStr", "1", "Int", szStream]
if b {
params.InsertAt(3, "Int", MAX_MEM_LEVEL, "Int", Z_DEFAULT_STRATEGY)
params.InsertAt(1, "Int", level, "Int", Z_DEFLATED)
}
Loop 1 {
res := DllCall(this.zlib.GetProcAddress( (b ? "de" : "in") . "flateInit2_" ), Ptr, &z_stream_s, params*)
if ( res != Z_OK && error := (b ? "de" : "in") . "flateInit2_: " . errors[-res] )
break
res := DllCall(this.zlib.GetProcAddress( (b ? "de" : "in") . "flate" ), Ptr, &z_stream_s, Int, Z_FINISH)
if ( res != Z_STREAM_END && error := (b ? "de" : "in") . "flate: " . errors[-res] )
break
res := DllCall(this.zlib.GetProcAddress( (b ? "de" : "in") . "flateEnd" ), Ptr, &z_stream_s)
( res != Z_OK && error := (b ? "de" : "in") . "flateEnd: " . errors[-res] )
}
if error
throw Exception(error)
Return outLen := NumGet(z_stream_s, A_PtrSize + 8 + A_PtrSize + 4, "UInt")
}
}
class GDIplus {
__New() {
if !DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr")
DllCall("LoadLibrary", "Str", "gdiplus")
VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", "UPtrP", pToken, "Ptr", &si, "Ptr", 0)
this.token := pToken
}
__Delete() {
DllCall("gdiplus\GdiplusShutdown", "Ptr", this.token)
if hModule := DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr")
DllCall("FreeLibrary", "Ptr", hModule)
}
CreateBitmapFromHBITMAP(hBitmap, Palette=0) {
DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "Ptr", hBitmap, "Ptr", Palette, "PtrP", pBitmap)
return pBitmap
}
SaveBitmap(pBitmap, ByRef info, Quality := 75, tobuff := "")
{
; info — если копируем в буфер, тогда расширение файла, если в файл, тогда путь к файлу
if tobuff
Extension := info
else
SplitPath, info,,, Extension
if Extension not in BMP,DIB,RLE,JPG,JPEG,JPE,JFIF,GIF,TIF,TIFF,PNG
return -1
DllCall("gdiplus\GdipGetImageEncodersSize", "UIntP", nCount, "UIntP", nSize)
VarSetCapacity(ci, nSize)
DllCall("gdiplus\GdipGetImageEncoders", "UInt", nCount, "UInt", nSize, "Ptr", &ci)
if !(nCount && nSize)
return -2
Loop, % nCount {
sString := StrGet(NumGet(ci, (idx := (48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize), "UTF-16")
if !InStr(sString, "*." Extension)
continue
pCodec := &ci+idx
break
}
if !pCodec
return -3
if RegExMatch(Extension, "i)^J(PG|PEG|PE|FIF)$") && Quality != 75 {
DllCall("gdiplus\GdipGetEncoderParameterListSize", "Ptr", pBitmap, "Ptr", pCodec, "UIntP", nSize)
VarSetCapacity(EncoderParameters, nSize, 0)
DllCall("gdiplus\GdipGetEncoderParameterList", "Ptr", pBitmap, "Ptr", pCodec, "UInt", nSize, "Ptr", &EncoderParameters)
Loop, % NumGet(EncoderParameters, "UInt")
{
elem := (24+A_PtrSize)*(A_Index-1) + 4 + (pad := A_PtrSize = 8 ? 4 : 0)
if (NumGet(EncoderParameters, elem+16, "UInt") = 1) && (NumGet(EncoderParameters, elem+20, "UInt") = 6)
{
p := elem+&EncoderParameters-pad-4
NumPut(Quality, NumGet(NumPut(4, NumPut(1, p+0)+20, "UInt")), "UInt")
break
}
}
}
if !tobuff
E := DllCall("gdiplus\GdipSaveImageToFile", "Ptr", pBitmap, "WStr", info, "Ptr", pCodec, "UInt", p ? p : 0)
else {
DllCall( "ole32\CreateStreamOnHGlobal", "UInt", 0, "Int", 1, "PtrP", pStream )
if !E := DllCall( "gdiplus\GdipSaveImageToStream", "Ptr", pBitmap, "Ptr", pStream, "Ptr", pCodec, "UInt", p ? p : 0 ) {
DllCall( "ole32\GetHGlobalFromStream", "Ptr", pStream, "PtrP", hData )
pData := DllCall( "GlobalLock", "Ptr", hData, "Ptr" )
nSize := DllCall( "GlobalSize", "Ptr", hData, "Ptr" )
VarSetCapacity( info, 0), VarSetCapacity( info, nSize, 0 )
DllCall( "RtlMoveMemory", "Ptr", &info, "Ptr", pData, "Ptr", nSize )
DllCall( "GlobalUnlock", "Ptr", hData )
DllCall( "GlobalFree", "Ptr", hData )
}
ObjRelease(pStream)
}
return E ? -4 : tobuff ? nSize : 0
}
DisposeImage(pBitmap) {
return DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap)
}
}
I know that there is another way to do the same (ZipRawMemory), but in this case I'd like to ensure, that the issue is related/not related to the script size.
I tried to compile with the AHK_L interpreter, the script worked correctly.
zlib1.dll (64 bit) is in the attachment.
- Attachments
-
- zlib1.zip
- (46.66 KiB) Downloaded 92 times
-
- Posts: 4326
- Joined: 29 Mar 2015, 09:41
- Contact:
Re: AHK_H v1.1.33.2 Compiled file doesn't handle the large script
@HotKeyIt
Another observation. My script works, when it's compiled with AHK_H v1.1.30.00. There is a difference: the resource is encrypted in it, while it is not encrypted in AHK_H v1.1.33.2, in both cases the resource was added using ;@Ahk2Exe-AddResource directive.
Another observation. My script works, when it's compiled with AHK_H v1.1.30.00. There is a difference: the resource is encrypted in it, while it is not encrypted in AHK_H v1.1.33.2, in both cases the resource was added using ;@Ahk2Exe-AddResource directive.
-
- Posts: 4326
- Joined: 29 Mar 2015, 09:41
- Contact:
Who is online
Users browsing this forum: No registered users and 21 guests