DllCall description Topic is solved

Discuss the future of the AutoHotkey language
User avatar
vvhitevvizard
Posts: 454
Joined: 25 Nov 2018, 10:15
Location: Russia

DllCall description

25 Dec 2018, 08:00

ReturnType: If the function returns a 32-bit signed integer (Int), BOOL, or nothing at all, ReturnType may be omitted. Otherwise, specify one of the argument types from the types table below. The asterisk suffix is also supported.
I guess, it has to be changed. Cuz the default seems to be uptr (same as for NumGet/NumPut). it means it might be uint64/int64 for x64 AHK version.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: DllCall description

26 Dec 2018, 03:38

How did you come to this conclusion? I think it works as expected.

Cheers :xmas:
User avatar
vvhitevvizard
Posts: 454
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: DllCall description

26 Dec 2018, 11:04

Helgef wrote:
26 Dec 2018, 03:38
How did you come to this conclusion? I think it works as expected.

Cheers :xmas:
Hmm, Indeed.
I created a small mcode which just returns some 64bit number.

Code: Select all

USE64
	mov	rax, 0x8800000000
	ret
By default its truncated to 32 bits after DllCall. And only with 'ptr' or 'unit64' I can obtain a full 64bit number. But don't u think its out of line with both NumGet and NumPut counterparts? :) I believe its expected to get uint64 for x64 by default.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: DllCall description  Topic is solved

26 Dec 2018, 11:41

I believe its expected to get uint64 for x64 by default.
it is not expected if you read the documentation. Int is probably the most common return type, at least for windows api, so it is a very good choice for the default imo.
don't u think its out of line with both NumGet and NumPut counterparts?
I don't see it that way, that those functions have a counterpart to dllcall's final parameter that is.

Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall description

26 Dec 2018, 14:56

Is the problem simply that AHK retrieves UInt64 as Int64?
You can store UInt64 numbers as Int64 and use Format to display them as UInt64.

Code: Select all

q:: ;AHK retrieves UInt64 as Int64
VarSetCapacity(vData, 8)
NumPut(-1, &vData, 0, "UInt64")
vNum := NumGet(&vData, 0, "UInt")
vPrompt1 := vNum "`r`n" Format("{:u}", vNum) "`r`n" Format("0x{:X}", vNum)
vNum := NumGet(&vData, 0, "UInt64")
vPrompt2 := vNum "`r`n" Format("{:u}", vNum) "`r`n" Format("0x{:X}", vNum)
MsgBox(vPrompt1 "`r`n`r`n" vPrompt2)
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: DllCall description

26 Dec 2018, 15:25

No that is not the problem.
The problem is that the default return type of DllCall is a 32 bit signed integer where as it's ptr sized for NumPut/NumGet.
Recommends AHK Studio
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall description

26 Dec 2018, 15:30

Thanks nnnik.

Default types:
DllCall: Int.
NumGet/NumPut: UPtr.

Where UPtr is: UInt (32-bit AHK), UInt64 (as Int64, 64-bit AHK).
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
vvhitevvizard
Posts: 454
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: DllCall description

04 Jan 2019, 10:51

Helgef wrote:
26 Dec 2018, 11:41
it is not expected if you read the documentation. Int is probably the most common return type, at least for windows api, so it is a very good choice for the default imo.
I missclicked it as solved. :) It is not actually. Cuz the majority of scripts intended to run with AHK64 skip the return value declaration cuz it happens to function as expected in most instances. DllCall returns a pointer which is just truncated. But that's the point - its possible the system may return an address 0x80000000 or higher (especially when using VirtualAlloc() or the likes to allocate ANY 64bit virtual address) and this way we get a very dangerous lurking error. And I inspected scripts - many and many of them do have this vulnerability.
It would be preferable for DllCall to return uint64 (aka ptr) the way NumGet/NumPut do. Just for consistency.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: DllCall description

04 Jan 2019, 11:43

Most of the WinAPI return types are DWORD status values where 0 stands for OK.
Many libraries are written poorly and inconsistently with other versions of AHK - this is a neglecteable fix and will not chang the overall quality of libraries found on this forum.
Recommends AHK Studio
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: DllCall description

04 Jan 2019, 11:57

It would be preferable for DllCall to return uint64 (aka ptr) the way NumGet/NumPut do. Just for consistency.
Consistency has no intrinsic value.

Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: DllCall description

04 Jan 2019, 12:06

I did some frequency counts on a list of dll functions I have, and 77% of return types are Int or UInt, suggesting the default of 'Int' for DllCall is right.

Code: Select all

611	i	58.7%
211	t	20.3%
192	ui	18.4%
10	ut	1.0%
8	uh	0.8%
5	h	0.5%
2	d	0.2%
2	uc	0.2%

1041	TOTAL	100%

803	i/ui	77.1%
221	t/ut	21.2%
13	uh/h	1.2%
2	d	0.2%
2	uc	0.2%
I use the same abbreviations as here:
WinApi
https://hotkeyit.github.io/v2/docs/commands/WinApi.htm
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: DllCall description

04 Jan 2019, 12:30

Helgef wrote:
04 Jan 2019, 11:57
It would be preferable for DllCall to return uint64 (aka ptr) the way NumGet/NumPut do. Just for consistency.
Consistency has no intrinsic value.

Cheers.
The value of consistency comes from the fact that it is not suprising to the developer.
When a pattern has been established breaking it will result in problems for the people trying to understand the larger construct.

That being said a group of 2 where both are different neither is a group nor a pattern.

Perhaps it would be best to remove the default return type so that people will be forced to define the DllCall properly.
Recommends AHK Studio
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: DllCall description

04 Jan 2019, 12:50

It would be surprising if all built in functions terminated the script, it would on the other hand make all functions consistent, that is, the consistency has no value in and of itself. Hence, to make an argument for changing the default, the op needs a better argument than consistency alone.

Otherwise I agree, and removing the default is a good suggestion.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: DllCall description

04 Jan 2019, 13:10

Helgef wrote:
04 Jan 2019, 12:50
It would be surprising if all built in functions terminated the script, it would on the other hand make all functions consistent, that is, the consistency has no value in and of itself. Hence, to make an argument for changing the default, the op needs a better argument than consistency alone.
In this case AHK functions would be inconsistent with functions from all other languages - it goes against the established pattern and the established expectations.
Consistency is not easily defined or found for one specific group since most things belong to multiple groups and categories.
If applied correctly it can make the language a lot easier to learn.

e.g. if we remove the default type from DllCall we should probably remove it from NumGet and NumPut too.
Recommends AHK Studio
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: DllCall description

04 Jan 2019, 13:27

I over exaggerated the example of course.

I do not necessarily agree or disagree with removing default for numputget. I don't think it will happen though.
feiyue
Posts: 349
Joined: 08 Aug 2014, 04:08

Re: DllCall description

04 Jan 2019, 21:48

In my opinion, Data types are only useful in building data structures.
It doesn't make much sense for the parameter type of DllCall.
Because each parameter is aligned to A_PtrSize bytes when it is pushed into the stack.
Just consider the 64-bit input and output values in 32-bit system,
And consider that floating-point numbers should be marked correctly.
Of course, it's useful that both STR and * types of AHK have internal automation.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: DllCall description

05 Jan 2019, 04:06

Feiyue, we talk about default return value, values are returned in volatile registers, meaning, if you specify a too wide type for the return, you can get garbage return, the current problem is that you might get truncated data when you don't specify a type and the default is too small. One solution is to remove the default to force users to consider the return type, changing it to something else is only swapping one problem for another.

Cheers.
User avatar
vvhitevvizard
Posts: 454
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: DllCall description

12 Jan 2019, 13:55

Helgef wrote:
04 Jan 2019, 12:50
It would be surprising if all built in functions terminated the script, it would on the other hand make all functions consistent, that is, the consistency has no value in and of itself. Hence, to make an argument for changing the default, the op needs a better argument than consistency alone.
Well, consistency is the key. Thats what makes some languages more popular than others actually. As nnnik stated, everything should be laid in easily memorizable patterns. AHK1.1 is an example of badly designed language - way too heterogeneous syntax, arguments order is messed up and so on. IMHO, there is no harm for 32 bit (DWORD) values to be returned as QWORDS for x64 AHK version by default - it wont break scripts logic.
jeeswg wrote:
04 Jan 2019, 12:06
I did some frequency counts on a list of dll functions I have, and 77% of return types are Int or UInt, suggesting the default of 'Int' for DllCall is right.
2nd popular retval is a pointer (which can be only 64bit for x64 code) nonetheless. It holds its place right after int32. :D
User avatar
vvhitevvizard
Posts: 454
Joined: 25 Nov 2018, 10:15
Location: Russia

Re: DllCall description

12 Jan 2019, 16:33

jeeswg wrote:
04 Jan 2019, 12:06
suggesting the default of 'Int' for DllCall is right.
U see, 32 bit values extended to 64 bit (with sign extension or zero extension) can be easily truncated:
-256 = 0xFFFFFFFFFFFFFF00, 256 = 0x0000000000000100. We just reject high DWORD w.o losing any significant digits -> 0xFFFFFF00 = -256, 0x00000100 = 256.

When a script expects 32bit int as default and gets 64bit int64, it gets the same value. But when we truncate full x64 pointer, we might corrupt it and it would lead to an exception.

So making a pointer size as default retval width (int for x86, int64 for x64) makes no harm and eliminates possible bugs. top 3 popular interpreting language Python has just integer (and float), no data width sub-type. More over, in Python, value of an integer is not restricted by the number of bits and can expand to the limit of the available memory. But that's another story. :D

2.
And just making the retval size descriptor mandatory would just increase code size, adding to redundancy.

btw, there is no "CDECL" for x64 code - x64 mode has only 1 calling convention so making that parameter mandatory is definitely not the best option.
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: DllCall description

12 Jan 2019, 17:20

When a script expects 32bit int as default and gets 64bit int64, it gets the same value. But when we truncate full x64 pointer, we might corrupt it and it would lead to an exception.
No it doesn't.
When values are returned from C functions the returning function just assigns the value to a specific register. When a 64 bit C function returns a 32 bit Integer it uses the RAX register.
When a 64 bit function returns a 64 bit Integer it assigns them to the RAX register. The thing is that these 2 are actually the same registers, except that EAX is just the lower 32 bits of RAX.
When assigning something to EAX the higher bits of RAX remain unchanged. Since DllCall now reads the value of RAX - after a 32 bit value has been returned - the higher bits will contain random data.
So no you dont get valid 32 bit results.
Recommends AHK Studio

Return to “AutoHotkey Development”

Who is online

Users browsing this forum: No registered users and 29 guests