Jump to content

Hard death of Autoit x64 with GDIPlus call


Go to solution Solved by LarsJ,

Recommended Posts

For those of you with AutoitX64, please run this code by saving it, right clicking, and selecting Run Script (x64).
 

#include <GDIPlus.au3>
_GDIPlus_Startup()

Local $hEffect = _GDIPlus_EffectCreateBlur(20)
Sleep(20000)

I get a hard failure (AutoItv3 Script has stopped working). Works fine on the 32bit version.

I tracked it down to the GdipCreateEffect DllCall in _GDIPlus_EffectCreate, but I don't know why it's happening.

Who else would I be?
Link to comment
Share on other sites

I need to investigate why the function crashes when running as x64 ->  0xC0000005 (access violation).

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

  • Solution

I'm pretty sure that if you are running 64 bit, the GUID in _GDIPlus_EffectCreate is transferred through the stack and not through two registers which is an impact of the current implementation.

Try this

#include <GDIPlus.au3>
_GDIPlus_Startup()

Local $hEffect = _GDIPlus_EffectCreateBlurX64(20)
MsgBox( 0, "", $hEffect )

Func _GDIPlus_EffectCreateBlurX64($fRadius = 10.0, $bExpandEdge = False)
  If $gbGDIP_V1_0 Then Return SetError(-1, 0, 0)

  Local $tEffectParameters = DllStructCreate($tagGDIP_EFFECTPARAMS_Blur)
  DllStructSetData($tEffectParameters, "Radius", $fRadius)
  DllStructSetData($tEffectParameters, "ExpandEdge", $bExpandEdge)

  Local $hEffect = _GDIPlus_EffectCreateX64($GDIP_BlurEffectGuid)
  If @error Then Return SetError(@error, @extended, 0)
  _GDIPlus_EffectSetParameters($hEffect, $tEffectParameters)
  If @error Then Return SetError(@error + 10, @extended, 0)

  Return $hEffect
EndFunc   ;==>_GDIPlus_EffectCreateBlurX64

Func _GDIPlus_EffectCreateX64($sEffectGUID)
  If $gbGDIP_V1_0 Then Return SetError(-1, 0, 0)

  Local $tGUID = _WinAPI_GUIDFromString($sEffectGUID)
  Local $tElem = DllStructCreate("uint64[2];", DllStructGetPtr($tGUID))

  Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateEffect", "ptr", DllStructGetPtr($tElem), "handle*", 0)
  If @error Then Return SetError(@error, @extended, 0)
  If $aResult[0] Then Return SetError(10, $aResult[0], 0)

  Return $aResult[2]
EndFunc   ;==>_GDIPlus_EffectCreateX64
Returns $hEffect <> 0.
Link to comment
Share on other sites

Thanks, Lars. I have no crash relating to that effect using your code.

I do have another crash. This time with some third-party code lifted from GDIP.au3 mixed with GDIPlus. I don't know where the problem is in this one either. Can you make a suggestion? I prefer to use StringFormatCreateTypographic instead of StringFormatCreate because of the way the type looks.

#include <GDIPlus.au3>
_GDIPlus_Startup()

Local $hFormat = _GDIPlus_StringFormatCreateTypographic()
MsgBox(0,"",$hFormat)
_GDIPlus_StringFormatSetAlign($hFormat, 1)
Sleep(20000)


; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_StringFormatCreateTypographic
; Description ...: Creates a generic, typographic StringFormat object
; Syntax.........: _GDIPlus_StringFormatCreateTypographic()
; Parameters ....: None
; Return values .: Success      - Pointer to a StringFormat object
;                  Failure      - 0 and either:
;                  |@error and @extended are set if DllCall failed
;                  |$GDIP_STATUS contains a non zero value specifying the error code
; Remarks .......: After you are done with the object, call _GDIPlus_StringFormatDispose to release the object resources
; Related .......: _GDIPlus_StringFormatDispose
; Link ..........; @@MsdnLink@@ GdipStringFormatGetGenericTypographic
; Example .......; No
; ===============================================================================================================================
Func _GDIPlus_StringFormatCreateTypographic()
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipStringFormatGetGenericTypographic", "int*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[1]
EndFunc   ;==>_GDIPlus_StringFormatCreateTypographic

I also don't know how to interpret a minus value from this function.

Who else would I be?
Link to comment
Share on other sites

http://msdn.microsoft.com/en-us/library/windows/desktop/ms534052(v=vs.85).aspx

 

 

Windows GDI+ exposes a flat API that consists of about 600 functions, which are implemented in Gdiplus.dll and declared in Gdiplusflat.h. The functions in the GDI+ flat API are wrapped by a collection of about 40 C++ classes. It is recommended that you do not directly call the functions in the flat API. Whenever you make calls to GDI+, you should do so by calling the methods and functions provided by the C++ wrappers. Microsoft Product Support Services will not provide support for code that calls the flat API directly. For more information on using these wrapper methods, see GDI+ Flat API.

Edited by BrewManNH

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

@BrewManNH, then the entire GDIPlus.au3 file has been built incorrectly? I would recommend you speak to the developers that they immediately change all the UDF code to comply with these wrappers!

Seriously, get back in line.

Who else would I be?
Link to comment
Share on other sites

Way to take something way past the intent. I only meant to show that the way they're being referenced isn't the recommended way, so if they crash don't be surprised.

And if all the GDI+ functions are referencing the functions in a non-recommended way, then by inference that would mean they were written wrong and should be looked at if anyone is using them and they encounter problems. Even Microsoft is telling you that it's wrong, and they wrote them.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

For those who are interested, I was able to achieve the same results without a crash by replacing _GDIPlus_StringFormatCreateTypographic with the following code that mimics its appearance.

Local $hFormat = _GDIPlus_StringFormatCreate(0x2000 + 0x4000 + 0x0004)
Who else would I be?
Link to comment
Share on other sites

I'm pretty sure that if you are running 64 bit, the GUID in _GDIPlus_EffectCreate is transferred through the stack and not through two registers which is an impact of the current implementation.

Try this

#include <GDIPlus.au3>
_GDIPlus_Startup()

Local $hEffect = _GDIPlus_EffectCreateBlurX64(20)
MsgBox( 0, "", $hEffect )

Func _GDIPlus_EffectCreateBlurX64($fRadius = 10.0, $bExpandEdge = False)
  If $gbGDIP_V1_0 Then Return SetError(-1, 0, 0)

  Local $tEffectParameters = DllStructCreate($tagGDIP_EFFECTPARAMS_Blur)
  DllStructSetData($tEffectParameters, "Radius", $fRadius)
  DllStructSetData($tEffectParameters, "ExpandEdge", $bExpandEdge)

  Local $hEffect = _GDIPlus_EffectCreateX64($GDIP_BlurEffectGuid)
  If @error Then Return SetError(@error, @extended, 0)
  _GDIPlus_EffectSetParameters($hEffect, $tEffectParameters)
  If @error Then Return SetError(@error + 10, @extended, 0)

  Return $hEffect
EndFunc   ;==>_GDIPlus_EffectCreateBlurX64

Func _GDIPlus_EffectCreateX64($sEffectGUID)
  If $gbGDIP_V1_0 Then Return SetError(-1, 0, 0)

  Local $tGUID = _WinAPI_GUIDFromString($sEffectGUID)
  Local $tElem = DllStructCreate("uint64[2];", DllStructGetPtr($tGUID))

  Local $aResult = DllCall($ghGDIPDll, "int", "GdipCreateEffect", "ptr", DllStructGetPtr($tElem), "handle*", 0)
  If @error Then Return SetError(@error, @extended, 0)
  If $aResult[0] Then Return SetError(10, $aResult[0], 0)

  Return $aResult[2]
EndFunc   ;==>_GDIPlus_EffectCreateX64
Returns $hEffect <> 0.

 

 

Thx, that was the solution!

I suggest this modification:

Func _GDIPlus_EffectCreate($sEffectGUID)
    If $gbGDIP_V1_0 Then Return SetError(-1, 0, 0)

    Local $tGUID = _WinAPI_GUIDFromString($sEffectGUID)
    Local $tElem = DllStructCreate("uint64[2];", DllStructGetPtr($tGUID)), $aResult

    If @AutoItX64 Then
      $aResult = DllCall($ghGDIPDll, "int", "GdipCreateEffect", "ptr", DllStructGetPtr($tElem), "handle*", 0)
      If @error Then Return SetError(@error, @extended, 0)
      If $aResult[0] Then Return SetError(10, $aResult[0], 0)

      Return $aResult[2]
    EndIf

    $aResult = DllCall($ghGDIPDll, "int", "GdipCreateEffect", "uint64", DllStructGetData($tElem, 1, 1), "uint64", DllStructGetData($tElem, 1, 2), "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[3]
EndFunc   ;==>_GDIPlus_EffectCreate

Can you test on your systems?

 

 

Thanks, Lars. I have no crash relating to that effect using your code.

I do have another crash. This time with some third-party code lifted from GDIP.au3 mixed with GDIPlus. I don't know where the problem is in this one either. Can you make a suggestion? I prefer to use StringFormatCreateTypographic instead of StringFormatCreate because of the way the type looks.

#include <GDIPlus.au3>
_GDIPlus_Startup()

Local $hFormat = _GDIPlus_StringFormatCreateTypographic()
MsgBox(0,"",$hFormat)
_GDIPlus_StringFormatSetAlign($hFormat, 1)
Sleep(20000)


; #FUNCTION# ====================================================================================================================
; Name...........: _GDIPlus_StringFormatCreateTypographic
; Description ...: Creates a generic, typographic StringFormat object
; Syntax.........: _GDIPlus_StringFormatCreateTypographic()
; Parameters ....: None
; Return values .: Success      - Pointer to a StringFormat object
;                  Failure      - 0 and either:
;                  |@error and @extended are set if DllCall failed
;                  |$GDIP_STATUS contains a non zero value specifying the error code
; Remarks .......: After you are done with the object, call _GDIPlus_StringFormatDispose to release the object resources
; Related .......: _GDIPlus_StringFormatDispose
; Link ..........; @@MsdnLink@@ GdipStringFormatGetGenericTypographic
; Example .......; No
; ===============================================================================================================================
Func _GDIPlus_StringFormatCreateTypographic()
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipStringFormatGetGenericTypographic", "int*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[1]
EndFunc   ;==>_GDIPlus_StringFormatCreateTypographic

I also don't know how to interpret a minus value from this function.

 

Use this instead:

Func _GDIPlus_StringFormatCreateTypographic()
    Local $aResult = DllCall($ghGDIPDll, "uint", "GdipStringFormatGetGenericTypographic", "ptr*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[1]
EndFunc   ;==>_GDIPlus_StringFormatCreateTypographic

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

UEZ, I think this is a little bit faster on 64 bit and not slower on 32 bit:

Func _GDIPlus_EffectCreate($sEffectGUID)
  If $gbGDIP_V1_0 Then Return SetError(-1, 0, 0)

  Local $tGUID = _WinAPI_GUIDFromString($sEffectGUID), $aResult

  If @AutoItX64 Then
    $aResult = DllCall($ghGDIPDll, "int", "GdipCreateEffect", "struct*", $tGUID, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[2]
  Else
    Local $tElem = DllStructCreate("uint64[2];", DllStructGetPtr($tGUID))
    $aResult = DllCall($ghGDIPDll, "int", "GdipCreateEffect", "uint64", DllStructGetData($tElem, 1, 1), "uint64", DllStructGetData($tElem, 1, 2), "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[3]
  EndIf
EndFunc   ;==>_GDIPlus_EffectCreate
Link to comment
Share on other sites

UEZ, I think this is a little bit faster on 64 bit and not slower on 32 bit:

Func _GDIPlus_EffectCreate($sEffectGUID)
  If $gbGDIP_V1_0 Then Return SetError(-1, 0, 0)

  Local $tGUID = _WinAPI_GUIDFromString($sEffectGUID), $aResult

  If @AutoItX64 Then
    $aResult = DllCall($ghGDIPDll, "int", "GdipCreateEffect", "struct*", $tGUID, "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[2]
  Else
    Local $tElem = DllStructCreate("uint64[2];", DllStructGetPtr($tGUID))
    $aResult = DllCall($ghGDIPDll, "int", "GdipCreateEffect", "uint64", DllStructGetData($tElem, 1, 1), "uint64", DllStructGetData($tElem, 1, 2), "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[3]
  EndIf
EndFunc   ;==>_GDIPlus_EffectCreate

 

Agree but instead of using If Then Else EndIf I would use this:

Func _GDIPlus_EffectCreate($sEffectGUID)
    If $gbGDIP_V1_0 Then Return SetError(-1, 0, 0)

    Local $tGUID = _WinAPI_GUIDFromString($sEffectGUID), $aResult

    If @AutoItX64 Then
      $aResult = DllCall($ghGDIPDll, "int", "GdipCreateEffect", "struct*", $tGUID, "handle*", 0)
      If @error Then Return SetError(@error, @extended, 0)
      If $aResult[0] Then Return SetError(10, $aResult[0], 0)

      Return $aResult[2]
    EndIf

    Local $tElem = DllStructCreate("uint64[2];", DllStructGetPtr($tGUID))
    $aResult = DllCall($ghGDIPDll, "int", "GdipCreateEffect", "uint64", DllStructGetData($tElem, 1, 1), "uint64", DllStructGetData($tElem, 1, 2), "handle*", 0)
    If @error Then Return SetError(@error, @extended, 0)
    If $aResult[0] Then Return SetError(10, $aResult[0], 0)

    Return $aResult[3]
EndFunc   ;==>_GDIPlus_EffectCreate

Anyhow, I didn't measure how "fast" this is compared to the the code from post#10.

Might be using Switch Case Case Else EndSwitch is faster...

 

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

  • Moderators

Hi,

The OT posts are now in "Chat". My comment on taking a deep breath and chilling before hitting the "Submit" button still stands. If the 2 protagonists wish to continue they should do so via PM as I strongly suggest that they not perturb the open forum any more. :naughty:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • 8 months later...

I just want to mention that this issue is not corrected in the include files with v3.3.12.0

The old code is still implemented, and causing the same hard crash. While I don't mind continuing to use the mod, I do have other hard crashes in AutoIt that I believe are also related to GDIPlus calls going crazy on x64. I would like to request a code review for GDIPlus on x64, since I don't have the expertise to review the calls.

Who else would I be?
Link to comment
Share on other sites

@this-is-me: should be fixed in the next latest beta version.

GDI+ v1.1. is only available for Win7 and above operating systems. If you want to use GDI+ v1.1 for Vista/Server 2008 you have to do some pre work to call the appropriate DLL.

 

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

As far as I can remember I did several test for this function.

Let's wait for the next beta release to test GDI+ x64 overall functionality.

Br,

UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...