GDI+ v2

Share the finished AutoHotkey v2 Scripts and libraries you made here. Please put the current version of AutoHotkey v2 you used in Square Brackets at the start of the topic title.
guest3456
Posts: 3134
Joined: 09 Oct 2013, 10:31

GDI+ v2

Post by guest3456 » 28 Jan 2020, 16:08

see the original GDIP thread for more info:
https://www.autohotkey.com/boards/viewtopic.php?t=6517

this version is backwards compatible with both AHK v1 and AHK v2 (as of 1.1.32 and v2-a108)
and also fixes some bugs from the original

link:
https://github.com/mmikeww/AHKv2-Gdip

i'm not the sole author of this, there are contributions from buliasz, justme, nnnik, iseahound, swagfag


User avatar
kczx3
Posts: 1141
Joined: 06 Oct 2015, 21:39

Re: GDI+ v2

Post by kczx3 » 28 Jan 2020, 19:51

Thanks for sharing! I’ve seen this repo out there before but it’s good to have a dedicated forum post with it for search ability.

malcev
Posts: 656
Joined: 12 Aug 2014, 12:37

Re: GDI+ v2

Post by malcev » 29 Jan 2020, 01:23

Why dont You remove all this?

Code: Select all

	Ptr := A_PtrSize ? "UPtr" : "UInt"
	, PtrA := A_PtrSize ? "UPtr*" : "UInt*"

guest3456
Posts: 3134
Joined: 09 Oct 2013, 10:31

Re: GDI+ v2

Post by guest3456 » 29 Jan 2020, 14:48

malcev wrote:
29 Jan 2020, 01:23
Why dont You remove all this?

Code: Select all

	Ptr := A_PtrSize ? "UPtr" : "UInt"
	, PtrA := A_PtrSize ? "UPtr*" : "UInt*"
eventually i will. too lazy


Helgef
Posts: 4459
Joined: 17 Jul 2016, 01:02
Contact:

Re: GDI+ v2

Post by Helgef » 02 Feb 2020, 03:11

Good job :thumbsup:. This will be very convenient for those (many) who are familiar with this lib and wants to start using v2.

Note that the gdip_startup() function is not safe for general use, this is probably not an error on your part, but rather by the original design. The easy fix, which will retain compatibility, is to just remove the if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr) line, that is, call LoadLibrary unconditionally. This makes the lib safe as long as each call to gdip_startup() is met by only one call to gdip_shutdown(). Some related information :arrow: weird script crash if LoadLibrary isnt used (this happen to relate to the same dll, but the problem of prematurly unloading a dll is of general importance.). An example of unsafe usage,

Code: Select all

t1 := Gdip_Startup()	; loads the library
t2 := Gdip_Startup()	; doesn't load the library
Gdip_Shutdown(t1)		; unloads the library, freeing it
Gdip_Shutdown(t2)		; undefined behaviour.
msgbox 					; might not be reached, due to either crash or exception
V2 users can add #DllLoad gdiplus, then the lib is safe regardless, and will perform much better.

Cheers.

guest3456
Posts: 3134
Joined: 09 Oct 2013, 10:31

Re: GDI+ v2

Post by guest3456 » 02 Feb 2020, 11:29

Helgef wrote:
02 Feb 2020, 03:11
Good job :thumbsup:. This will be very convenient for those (many) who are familiar with this lib and wants to start using v2.

Note that the gdip_startup() function is not safe for general use, this is probably not an error on your part, but rather by the original design. The easy fix, which will retain compatibility, is to just remove the if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr) line, that is, call LoadLibrary unconditionally. This makes the lib safe as long as each call to gdip_startup() is met by only one call to gdip_shutdown(). Some related information :arrow: weird script crash if LoadLibrary isnt used (this happen to relate to the same dll, but the problem of prematurly unloading a dll is of general importance.). An example of unsafe usage,

Code: Select all

t1 := Gdip_Startup()	; loads the library
t2 := Gdip_Startup()	; doesn't load the library
Gdip_Shutdown(t1)		; unloads the library, freeing it
Gdip_Shutdown(t2)		; undefined behaviour.
msgbox 					; might not be reached, due to either crash or exception
i'm not sure i understand. i read the linked thread, and had the same thoughts as swagfag in there. how is Gdip_Startup() the problem in the code above? how would explicitly loading the dll twice in the 2 startup calls, avoid the potential crash in the 2nd shutdown?


Helgef
Posts: 4459
Joined: 17 Jul 2016, 01:02
Contact:

Re: GDI+ v2

Post by Helgef » 02 Feb 2020, 12:10

Each time you call loadlibrary you increase the reference count for that dll by one, each call to freelibrary decreases the reference count by one. Only when the reference count reaches zero, will the dll be truly freed. Hence, calling loadlibrary on every call to gdip_startup ensures the dll is not prematurely freed when you call gdip_shutdown.

Cheers.

iseahound
Posts: 610
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: GDI+ v2

Post by iseahound » 18 May 2020, 13:49

So you're saying that LoadLibrary has a built in reference count? But gdipstartup doesn't and it causes heavy instability when it's called twice. Any ideas on how to solve this or to just define our own reference counter.

malcev
Posts: 656
Joined: 12 Aug 2014, 12:37

Re: GDI+ v2

Post by malcev » 18 May 2020, 14:37

The minus of this library is that there is no error checking.

Code: Select all

if !DllCall("GetModuleHandle", "str", "gdiplus", "ptr")
   DllCall("LoadLibrary", "str", "gdiplus")
VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", A_PtrSize ? "UPtr*" : "uint*", pToken, Ptr, &si, Ptr, 0)

VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
DllCall("gdiplus\GdiplusStartup", A_PtrSize ? "UPtr*" : "uint*", pToken1, Ptr, &si, Ptr, 0)

msgbox % DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
if hModule := DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
   DllCall("FreeLibrary", Ptr, hModule)

msgbox % DllCall("gdiplus\GdiplusShutdown", Ptr, pToken1)
I think that it will be OK if We dont call DllCall("FreeLibrary") at all, because dll automatically unload when You close process.
Or if You need to free library, then free it in separate function.

Helgef
Posts: 4459
Joined: 17 Jul 2016, 01:02
Contact:

Re: GDI+ v2

Post by Helgef » 19 May 2020, 09:18

iseahound wrote:So you're saying that LoadLibrary has a built in reference count?
Dlls loaded by LoadLibrary has a reference count. It is incremented by LoadLibrary (+1) and decremented by FreeLibrary (-1).
But gdipstartup doesn't and it causes heavy instability when it's called twice
GdiplusStartup doesn't affect the reference count of the gdiplus dll. You can call GdiplusStartup as many times as you like. But don't unload the dll until you are done with it.
Any ideas on how to solve this
:arrow: Yes. In addition to that, as @malcev said, you can skip unloading it at all if you like, it will be unloaded when the program terminates.
malcev wrote:The minus of this library is that there is no error checking.
I agree, and it is a big minus imo.

Cheers.

iseahound
Posts: 610
Joined: 13 Aug 2016, 21:04
GitHub: iseahound

Re: GDI+ v2

Post by iseahound » 19 May 2020, 13:04

Don't call GdiplusStartup multiple times as each call returns a different pToken. Having multiple pTokens in the same script will cause crashes. Hard to explain, don't call that twice lol.

Helgef
Posts: 4459
Joined: 17 Jul 2016, 01:02
Contact:

Re: GDI+ v2

Post by Helgef » 19 May 2020, 13:16

No,
You can call GdiplusStartup as many times as you like. But don't unload the dll until you are done with it.
malcev's code crashes / throws / behaves unexpectedly because the library is unloaded prematurely

Post Reply

Return to “AutoHotkey v2 Scripts and Functions”