DllCall causes AHK to crash with Access Violation Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
hobboy
Posts: 41
Joined: 05 Jan 2016, 09:59

DllCall causes AHK to crash with Access Violation

24 Mar 2018, 02:50

AHK U32bit
I have the code that calls a dll function. The function returns a 4 byte AStr into the variable I pass:

Code: Select all

VarSetCapacity(mystring, 4)
DllCall("some\dllfunction","AStr", mystring, "Cdecl")
Running this code causes AHK to crash on this line with an error
"Unhandled exception at 0x0041BE79 in AutoHotkey.exe: 0xC0000005: Access violation reading location 0x20202036."
(Note that I'm unsure whether I need to set variable size to 8 bytes instead of 4 since I'm using a unicode build, but this doesn't fix the crash)

However, if I instead make the string directly the DllCall works fine:

Code: Select all

mystring="AAAA"
DllCall("some\dllfunction","AStr", mystring, "Cdecl")
If I instead do the 1st function with "WStr" it works fine, however I'm fairly sure AStr is the required type (function requires an LPSTR). Can someone explain what I'm doing wrong?

I doubt this is a bug, but I don't understand why VarSetCapacity(mystring, 4) cannot be used with the AStr DllCall and WStr can.
Helgef
Posts: 3890
Joined: 17 Jul 2016, 01:02
Contact:

Re: DllCall causes AHK to crash with Access Violation

24 Mar 2018, 04:15

If "Str" or the equivalent type for the current build is used as a parameter, the address of the string or var is passed to the function, otherwise a temporary copy of the string is created in the desired format and passed instead. As a general rule, "AStr" and "WStr" should not be used if the function writes a value into that parameter.
src

Cheers.
just me
Posts: 6464
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: DllCall causes AHK to crash with Access Violation

24 Mar 2018, 04:29

Try

Code: Select all

VarSetCapacity(mystring, 4, 0) ; initialize the variable with NULL bytes
If you use AStr with AHK Unicode, AHK tries to convert the string expected in mystring from Unicode to ANSI. If you don't initialize mystring, it will contain arbitrary contents. That might cause problems within the conversion.

On the other hand, Helgef is right. You might consider to pass a pointer to mystring and get the string using StrGet().
Helgef
Posts: 3890
Joined: 17 Jul 2016, 01:02
Contact:

Re: DllCall causes AHK to crash with Access Violation

24 Mar 2018, 04:44

It seems you need to initialise to something non zero just me. I guess AHK doesn't consider the capacity of the input variable. so varsetcapacity(mystring, 4, 1) would work (warning, not guaranteed to be null terminated). But I recommend using "ptr", &mystring since the docs says you shouldn't use w/astr if the function writes to it.

cheers.
just me
Posts: 6464
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: DllCall causes AHK to crash with Access Violation

24 Mar 2018, 05:28

Hi Helgef,

I didn't test it. The first thing coming into my mind was
WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, -1, ...)
But I didn't look into the source code.
The function returns a 4 byte AStr into the variable I pass
AStr should work in this case.
Helgef
Posts: 3890
Joined: 17 Jul 2016, 01:02
Contact:

Re: DllCall causes AHK to crash with Access Violation  Topic is solved

24 Mar 2018, 07:15

Hi just me :wave:
-1
If this parameter is -1, the function processes the entire input string,
That would explain why you need to initialise the buffer ;). When you pass mystring from varsetcapacity(mystring,4), it will be converted to an astr of the same length, since, most likely mystring only contains zeros, it is a string of zero length, consequently, the dll function writes outside of the temporary string buffer passed to it, problem. If you do mystring := "AAAA", ahk passes a pointer to an astr of length 4 (+ null terminator), no problems. When you use wstr on unicode build, ahk only passes &mystring, and then updates the string length after the call.

You'd get the same problem if you use wstr with a zero length string on ANSI build.

Cheers.
hobboy
Posts: 41
Joined: 05 Jan 2016, 09:59

Re: DllCall causes AHK to crash with Access Violation

24 Mar 2018, 10:44

Thanks Helgef and just me, that makes more sense to me :)

Can you point me to any documentation or code/info about the below quote, because I wasn't able to find this info and would like to learn more:
Helgef wrote: you do mystring := "AAAA", ahk passes a pointer to an astr of length 4 (+ null terminator)
(Specifically I don't know where you got the info about ahk passing a pointer and why this helps)
I was hoping I could use AStr to automatically convert my unicode strings into ANSI. Looks like I might need to manually convert to ANSI before the DllCall.

edit: I'll sleep on it and it will probably be clear in the morning
Last edited by hobboy on 24 Mar 2018, 11:00, edited 1 time in total.
just me
Posts: 6464
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: DllCall causes AHK to crash with Access Violation

24 Mar 2018, 10:50

:idea:

Thanks Helgef,
You wrote:I guess AHK doesn't consider the capacity of the input variable ...
I missed this point. I supposed that AHK would pass a buffer with a minimum size corresponding to the capacity of the passed variable. It doesn't seem so.
lexikos
Posts: 6483
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: DllCall causes AHK to crash with Access Violation

24 Mar 2018, 21:47

Some ANSI code pages are multi-byte, so I believe it is possible for one Unicode character to produce two bytes. In that case, the buffer would need to be twice the capacity of the input variable. That could be especially wasteful if the variable has a much higher capacity than needed and the value is for input only.

Also consider that the buffer size often has to be passed to the function, but if the actual buffer size is automatically calculated based on guesses or worst-case conversion, the value you pass may be wrong.

The variable's capacity really isn't relevant if the function isn't writing into the variable. DllCall does assign back to the variable after the function returns, but at that point the variable will be expanded automatically if needed.

For v2, "WStr" is always equivalent to "Str", because there's no ANSI build. The variable itself would be passed in that case, and would be safe to write to (if its capacity has been set correctly).

Return to “Ask For Help”

Who is online

Users browsing this forum: Bing [Bot], flyingDman, Google [Bot], MIRKOSOFT, omar, ph4nton and 194 guests