Page 1 of 1

DllCall - diff between "Ptr" &var and "Ptr*" var

Posted: 12 Aug 2014, 12:25
by trismarck
According to the documentation on DllCall, Ptr* passes _an address_ [of the string buffer] of the variable instead of the 'contents' of the variable. If that's the case then why those two calls produce different results? The type of the second argument is PVOID.

Code: Select all

SystemInformationClass := 16
VarSetCapacity(SystemInformation, SystemInformationLength := 0x100000)
VarSetCapacity(ReturnLength, 4)
status := DllCall("ntdll.dll\NtQuerySystemInformation"
		, "UInt", SystemInformationClass
		;, "Ptr", &SystemInformation	; works
		, "Ptr*", SystemInformation		; fails
		, "UInt", SystemInformationLength
		
		, "UInt*", ReturnLength
		, "Int")

SetFormat, IntegerFast, Hex
status &= 0xFFFFFFFF, status .= ""
setformat, IntegerFast, Dec
MsgBox % status ; 0xC0000005

Re: DllCall - diff between "Ptr" &var and "Ptr*" var

Posted: 12 Aug 2014, 13:20
by HotKeyIt
As far as I understand:
Ptr*, var passes the address of variable Int64 buffer where Ptr, &var passes the string buffer.

In AutoHotkey_H Ptr*, var equals PTR, getvar(var:=0).

Re: DllCall - diff between "Ptr" &var and "Ptr*" var

Posted: 12 Aug 2014, 13:58
by trismarck
That is perfectly logical, thank you HotkeyIt.

Re: DllCall - diff between "Ptr" &var and "Ptr*" var

Posted: 13 Aug 2014, 01:11
by just me
Aside from implementation details:
Ptr can also be used with the * or P suffix; it should be used with functions that output a pointer via LPVOID* or similar.

Source: DllCall -> Types of Arguments and Return Values -> Ptr
A type of PtrP or Ptr* will receive a pointer-sized value when DllCall returns.

Re: DllCall - diff between "Ptr" &var and "Ptr*" var

Posted: 13 Aug 2014, 01:40
by lexikos
trismarck wrote:According to the documentation on DllCall, Ptr* passes _an address_ [of the string buffer] of the variable instead of the 'contents' of the variable.
trismarck is probably referring to this:
DllCall wrote:For example, the following call would pass the contents of MyVar to MyFunction by address, but would also update MyVar to reflect any changes made to it by MyFunction: DllCall("MyDll\MyFunction", "Int*", MyVar).
This is a bit misleading; the contents (value) of MyVar is copied into a temporary variable of the appropriate type, and the address of this temporary variable (which is, by extension, the address of the value that MyVar contained) is passed.

However,
An asterisk should not be used for string types such as LPTSTR, pointers to structures such as LPRECT, or arrays
...
Since variables in AutoHotkey have no fixed type, the address passed to the function points to temporary memory rather than the variable itself.