Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[Class] [AHK_L/v2] _MemoryLibrary


  • Please log in to reply
18 replies to this topic
HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

Based on MemoryModule from fancycode.
Same functionality is used in AutoHotkey_H/AutoHotkey.dll.

Note :!: You will need latest AutoHotkey_L or AutoHotkey_H to use these functions.

Reqires also latest _Struct.

Download _MemoryLibrary.ahk - or - _MemoryLibrary.ahk (v2 version)

 

new _MemoryLibrary("Path to dll" || &pointer to data) ; Similar to DllCall("LoadLibrary","Str","Path to dll","PTR")
.GetProcAddress("funcname") ;Receive the pointer to a function, similar to DllCall("GetProcAddress","ptr",moduleHandlePtr,"AStr","funcname","PTR")
.Free() ; Free resources, similar to DllCall("FreeLibrary","PTR",moduleHandlePtr)

Example

If (!FileExist(A_ScriptDir "\AutoHotkey.dll") || !(MemLib:=new _MemoryLibrary(A_ScriptDir "\AutoHotkey.dll"))){
MsgBox AutoHotkey.dll was not found or could not be loaded
ExitApp
}
;Second method by passing the data pointer
FileRead,data,*c %A_ScriptDir%\AutoHotkey.dll
NewMemLib:=new _MemoryLibrary(&data)

DllCall(MemLib.GetProcAddress("ahktextdll"),"Str","MsgBox Hello from Thread","Str","","Str","") ; start first AutoHotkey.dll thread
DllCall(NewMemLib.GetProcAddress("ahktextdll"),"Str","MsgBox Hello from other Thread","Str","","Str","") ; start another AutoHotkey.dll thread
Sleep 1000
MsgBox AutoHotkey.dll started, press OK to terminate.
DllCall(MemLib.GetProcAddress("ahkterminate")), MemLib.Free()
DllCall(NewMemLib.GetProcAddress("ahkterminate")), NewMemLib.Free()
MsgBox AutoHotkey.dll threads terminated and memory freed


hughman
  • Members
  • 192 posts
  • Last active: Feb 14 2016 06:59 AM
  • Joined: 11 Feb 2007
class version of MemoryLoadLibrary?

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Yes, newest _Struct version can handle that :D

  • Guests
  • Last active:
  • Joined: --
Hi HotkeyIt,

Is it possible with this library to load an image file in a resource file of a compiled script which is installed with the FileInstall command? And if possible, I'd like to show the image in a Gui and unload the library after destroying the Gui.

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Yes it is possible but needs to be done manually.
In BuildImportTable you can see how the manifest from resource is read. Same way you would need to find and read image resource.

  • Guests
  • Last active:
  • Joined: --

Yes it is possible but needs to be done manually.
In BuildImportTable you can see how the manifest from resource is read. Same way you would need to find and read image resource.

Does it mean this library is not primarily meant for such a purpose?

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
That is correct, but based on the code you could build one that reads resouce data from included exe or expand _MemoryLibrary it to be able to do that.

  • Guests
  • Last active:
  • Joined: --
Thanks for the comment. I'm not quite sure what you meant though due to my limited knowledge on this subject and I have a trouble figuring out how to use the library.

I could show a bmp image on a gui window from buffer.
<!-- m -->http://www.autohotke...480.html#507480<!-- m -->
And I could load an image from a resource with this method.
<!-- m -->http://www.autohotke...046.html#507046<!-- m -->

But I cannot unload the library (free the memory) after using it. That is the problem and your library seems to be able to handle it. Would you mind writing a small example for this if it's not difficult for you? Thanks.

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
I assume this is because you have to free the resource before you can unload the dll, try this:
; LoadResourceDemo.ahk

SelfCompile()



; Load resource and retrieve address and size.

if size := LoadScriptResource([color=red]data[/color],"LoadResourceDemo.ahk")

{

    ; Retrieve text, assuming UTF-8 encoding.

    text := StrGet([color=red]&data[/color], size, "UTF-8")

    ; Display text in GUI.

    Gui Add, Edit, ReadOnly W600 H400, %text%

    Gui Show

    return

}

else

    MsgBox 16,, Failed to load resource.



GuiClose:

GuiEscape:

ExitApp



LoadScriptResource(ByRef Data,Name, Type = 10)

{

    lib := DllCall("GetModuleHandle", "ptr", 0, "ptr")

    res := DllCall("FindResource", "ptr", lib, "str", Name, "ptr", Type, "ptr")

    DataSize := DllCall("SizeofResource", "ptr", lib, "ptr", res, "uint")

    hresdata := DllCall("LoadResource", "ptr", lib, "ptr", res, "ptr")

    [color=red]VarSetCapacity(Data,DataSize)

    DllCall("RtlMoveMemory","PTR",&Data,"PTR",DllCall("LockResource", "ptr", hresdata, "ptr"),"UInt",DataSize)

    DllCall("FreeResource","PTR",hresdata)

    return DataSize[/color]

}



SelfCompile()

{

    if A_IsCompiled

        return

    ; Self-compile-and-run.

    [color=red]If FileExist(A_AhkPath "\..\Compiler\Ahk2Exe.exe")

        RunWait, %A_AhkPath%\..\Compiler\Ahk2Exe.exe /in "%A_ScriptFullPath%"[/color]

    else RunWait, %A_AhkPath%\..\[color=red]..\[/color]Compiler\Ahk2Exe.exe /in "%A_ScriptFullPath%"

    Run LoadResourceDemo.exe

    ExitApp

   

    ; Not executed by AutoHotkey, but interpreted by Ahk2Exe:

    FileInstall, LoadResourceDemo.ahk, ~

}


  • Guests
  • Last active:
  • Joined: --
HotKeyIt, thanks for the code.

It seems my question didn't belong to this thread. And I cannot know whether your code frees the memory allocated for the loaded resources since the memory usage of the compiled script becomes larger than the one using Lexikos's function.

I noticed the memory usage of the compiled script is affected by the size of installed resource files. I thought this was due to the loaded data with LoadScriptResource() function but it seems not. Also I found another issue that a bitmap image doesn't load with the function posted in the link. I have to solve these problems first.

So thanks for having spent time for my question and sorry for having bothered you. I'll post my question in Ask for Help.

tmplinshi
  • Members
  • 245 posts
  • Last active: Mar 12 2015 02:29 PM
  • Joined: 06 Apr 2012
Hi HotKeyIt,
 
Your example works, but loading BASSMOD.dll will prompt 'ERROR: BuildImportTable failed':
FileRead, data, *c %A_ScriptDir%\BASSMOD.dll
MemLib := new _MemoryLibrary(&data)
So the BASSMOD.dll is the reason, could you have a look at it? bassmod.dll can be downloaded from http://us.un4seen.co...s/bassmod20.zip

(Tested on XP_SP3, and AHK_L A32/U32)

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

This is because BASSMOD.dll is packed with a compressor like upx and mpress and we can't read its resources which we need for WinSxS to work.



tmplinshi
  • Members
  • 245 posts
  • Last active: Mar 12 2015 02:29 PM
  • Joined: 06 Apr 2012
Thank you for the answer. I will search for "bassmod.dll unpack"...

tmplinshi
  • Members
  • 245 posts
  • Last active: Mar 12 2015 02:29 PM
  • Joined: 06 Apr 2012
I Found fmod.dll, it can play from memory grin.png
But sometimes the script will crash when executing MemLib.Free()
Spoiler

Download all files here: http://tmplinshi.goo...od/fmod_demo.7z

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

I had a pending update for _Struct class, can you re-download and try again.

Also as I understand you need to call [email protected] when you finished using module.