#NoEnv
; DllCall("LoadLibrary", "Str", "Gdiplus.dll") ; crash on exit if this is commented out
VarSetCapacity(GdiplusStartupInput, 12 + A_PtrSize, 0)
NumPut(1, GdiplusStartupInput, 0, "UInt")
DllCall("Gdiplus.dll\GdiplusStartup", "UPtr*", token, "Ptr", &GdiplusStartupInput, "Ptr", 0)
Esc::
DllCall("Gdiplus.dll\GdiplusShutdown", "UPtr", token) ; crash if loadlibrary wasnt used
ExitApp
why is it that calling GdiplusShutdown() without an explicit prior LoadLibrary() crashes my script? the dllcall should be managing loadlibrary/freelibrary internally, so why does it make a difference
Re: weird script crash if LoadLibrary isnt used Topic is solved
Posted: 13 Feb 2019, 05:43
by Helgef
As you say, dllcall calls FreeLibrary before returning. so your token is invalid. Using it is undefined behaviour, which might or might not cause a crash, or something else or nothing.
just me wrote:Longer story:
well put
Cheers.
Re: weird script crash if LoadLibrary isnt used
Posted: 13 Feb 2019, 06:04
by just me
Longer story:
Some DLLs initialize memory and/or other resources for the calling process/thread when loaded or initialized by functions like GdiplusStartup(). The resources are used by subsequent function calls and stay valid until the DLL is freed/unloaded or 'uninitialized' (e.g. GdiplusShutdown()). If such a DLL is unloaded prematurely, your script may crash if you call other DLL functions afterwards.
Re: weird script crash if LoadLibrary isnt used
Posted: 13 Feb 2019, 07:28
by swagfag
im not entirely convinced thats whats happening. consider these scripts:
so if i can manually load/unload gdiplus.dll however many times i want and GdiplusShutdown() succeeds provided the dll is loaded at the time of calling it, why is is then that the 2 naked Startup/Shutdown dllcalls back-to-back fail. #1 should be functionally equivalent to #3
furthermore, i dont think its an issue with feeding GdiplusShutdown() bogus tokens. Startup gives me tokens in the range 16850796 atm, and the following script ran without crashing:
helgef wrote:it is undefined behaviour, which might or might not cause a crash, or something else or nothing.
Btw, #2 doesn't crash for me on 32 build, but errorlevel shows 0xc0000005, that is, access violation, which is in line with just me's points.
Cheers
Re: weird script crash if LoadLibrary isnt used
Posted: 13 Feb 2019, 07:57
by swagfag
anyways, i guess undefined behavior's gonna do what undefined behavior's gonna do
ill just go ahead and file this under my dllcall gotchas:
if its not User32.dll, Kernel32.dll, ComCtl32.dll, Gdi32.dll -> LoadLibrary()
Re: weird script crash if LoadLibrary isnt used
Posted: 13 Feb 2019, 08:20
by Helgef
if its not User32.dll, Kernel32.dll, ComCtl32.dll, Gdi32.dll -> LoadLibrary()
That is not entirely correct. You need to specify the path/name of the dll when it is not one of those, however, the dll might still be loaded. You can check if a dll needs to be loaded by calling GetModuleHandle.
Cheers.
As a side note, I have implemented a #LoadLibrary directive, to load dlls at load time, although I might redesign the implemenation, I didn't decide if I will make PR or not. Edit: I changed it and made a PR: #136.
Re: weird script crash if LoadLibrary isnt used
Posted: 12 May 2019, 10:52
by swagfag
meaning, if u have User32.dll, for example, whose dependencies include, among others, powrprof.dll, that AHK will automatically load powrprof.dll by default, however if u wanted to use the functions from powrprof.dll, DllCall("powrprof.dll\whatever", ...) would still be required
You can check if a dll needs to be loaded by calling GetModuleHandle.
Even if a particular dll was loaded, you do not have any general guarantees that something, i.e., the program or some script lib you use, will not unload it, so you should probably load any dlls which you are unsure about.