Questions about DllCall's

Get help with using AutoHotkey and its commands and hotkeys
User avatar
jNizM
Posts: 2317
Joined: 30 Sep 2013, 01:33
GitHub: jNizM
Contact:

Questions about DllCall's

29 Jan 2015, 02:54

Post your questions about DllCall's here!

My first questions is:

_Out_ LPDWORD works with UInt* (UIntP) and Ptr* (PtrP)
Which one should I prefer?



Everyone can add here questions about DllCall's (Like the RegEx Questions Topic on the old Forum)
[AHK] 1.1.28.02 x64 Unicode | [WIN] 10 Pro (Version 1803) x64 | [GitHub] Profile
Donations are appreciated if I could help you
RHCP
Posts: 182
Joined: 30 Sep 2013, 10:59

Re: Questions about DllCall's

29 Jan 2015, 03:45

LPDWORD is a long pointer (pointer) to a DWORD. A DWORD is an unsigned 32bit integer, so "UInt*" would be my preference.

I could be wrong here, but I think "Ptr*" may cause issues in 32 bit AHK builds when the return value is extreme i.e. overflows. If the function returned 0xFFFFFFFF (the max value for a UInt) "Ptr*" would interpret this value as -1 due to the fact that in 32 bit builds of AHK "Ptr" is a signed integer.
User avatar
jNizM
Posts: 2317
Joined: 30 Sep 2013, 01:33
GitHub: jNizM
Contact:

Re: Questions about DllCall's

29 Jan 2015, 05:09

Ahh ok.. Thx for Info RHCP
[AHK] 1.1.28.02 x64 Unicode | [WIN] 10 Pro (Version 1803) x64 | [GitHub] Profile
Donations are appreciated if I could help you
just me
Posts: 5397
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Questions about DllCall's

29 Jan 2015, 06:40

For this question you'll find the answer in the docs: ;)
* or P (suffix):
In general, an asterisk is used whenever a function has an argument type or return type that starts with "LP". The most common example is LPDWORD, which is a pointer to a DWORD. Since a DWORD is an unsigned 32-bit integer, use "UInt*" or "UintP" to represent LPDWORD.
Source
User avatar
evilC
Posts: 4183
Joined: 27 Feb 2014, 12:30

Re: Questions about DllCall's

29 Jan 2015, 07:03

This thread could be hugely useful to me, I am trying to add joystick support via HID, and it is utterly kicking my arse.

Once I learn all these rules etc, it shouldn't be too hard, but at the moment the learning curve is pretty steep.

A large part of my problem is knowing when to use & and ByRef.

So given a function spec from MSDN:

Code: [Select all] [Download] GeSHi © Codebox Plus

UINT WINAPI GetRawInputData(
_In_ HRAWINPUT hRawInput,
_In_ UINT uiCommand,
_Out_opt_ LPVOID pData,
_Inout_ PUINT pcbSize,
_In_ UINT cbSizeHeader
);


How would I know which params require passing by reference?
Only the stuff that needs to come back out again? (ie _Out_ stuff?)

Would this syntax be correct?

(I know I haven't done VarSetCapacity on pData, but that is outside the scope of this question)

Code: [Select all] [Download] GeSHi © Codebox Plus

GetRawInputData(hRawInput, uiCommand, &pData, &pcbSize, cbSizeHeader )

GetRawInputData(hRawInput, uiCommand, ByRef pData, ByRef pcbSize, cbSizeHeader ){
return DllCall("Hidp\GetRawInputData", "Uint", hRawInput, "Uint", uiCommand, "Ptr", pData, "UintP", pcbSize, "Uint", cbSizeHeader)
}
User avatar
evilC
Posts: 4183
Joined: 27 Feb 2014, 12:30

Re: Questions about DllCall's

29 Jan 2015, 07:24

Also, I am not quite sure I get how to work out correct size.

For example, the GetRawInputDeviceList DLL Call in AHKHID is like so:
DllCall("GetRawInputDeviceList", "Ptr", 0, "UInt*", iCount, "UInt", A_PtrSize * 2)

The relevant docs say:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



So I open visual studio and insert in:

Code: [Select all] [Download] GeSHi © Codebox Plus

size = sizeof(RAWINPUTDEVICELIST);

And get the result 8

Is this number affected by word length? How would I know if visual studio was running as x86 or x64?

So if running 32-bit AHK, A_PtrSize is 4, so 2*4 = 8, as expected.
But if on 64-bit AHK, A_PtrSize is 8, so 2*8 = 16 - is this correct on x64 AHK?

Or is that purely telling me that VS is operating as 32-bit, so I should treat all the results in VS as what I would use for 32-bit AHK?
User avatar
boiler
Posts: 2371
Joined: 21 Dec 2014, 02:44

Re: Questions about DllCall's

29 Jan 2015, 08:29

evilC wrote:How would I know which params require passing by reference?
Only the stuff that needs to come back out again? (ie _Out_ stuff?)

That's how I always interpreted the WINAPI stuff, and it seems to be consistent. Also the "P" that's part of the "PUINT" indicates that it's a pointer to a UINT type, so it is telling you where to find the UINT value it stored.
User avatar
jNizM
Posts: 2317
Joined: 30 Sep 2013, 01:33
GitHub: jNizM
Contact:

Re: Questions about DllCall's

29 Jan 2015, 08:57

thx just me
The next one is _Out_opt_ PULARGE_INTEGER (A pointer to a variable...)
I saw different scripts with UInt64 or Int64* or something else

eg

Code: [Select all] [Download] GeSHi © Codebox Plus

VarSetCapacity(name, size, 0)
DllCall("xxx.dll", "UInt64", &name) ;Int64* or something else
NumGet(name, 0, "UInt64) ;Int64* or something else


What should I use or which one should I prefer?
Last edited by jNizM on 29 Jan 2015, 09:00, edited 3 times in total.
[AHK] 1.1.28.02 x64 Unicode | [WIN] 10 Pro (Version 1803) x64 | [GitHub] Profile
Donations are appreciated if I could help you
User avatar
evilC
Posts: 4183
Joined: 27 Feb 2014, 12:30

Re: Questions about DllCall's

29 Jan 2015, 08:59

Aagh! I cannot understand what is going wrong in this code.

Why is the OUT: msgbox not the same as IN: ?

Code: [Select all] [Expand] [Download] (Script.ahk)GeSHi © Codebox Plus

just me
Posts: 5397
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Questions about DllCall's

29 Jan 2015, 09:00

evilC wrote:Also, I am not quite sure I get how to work out correct size.

That's really complicated stuff. Let me try to explain this simple sample:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



A large part of my problem is knowing when to use & and ByRef.
Whenever you need to pass a buffer to be filled by the API function, you have to pass its address using &Buffer.
User avatar
evilC
Posts: 4183
Joined: 27 Feb 2014, 12:30

Re: Questions about DllCall's

29 Jan 2015, 09:06

"By default, the whole length of a structure has to be a multiple of the maximum field size."

hmm, which maximum?

You mean it has to be a multiple of the biggest field size?
So if you have something that uses 3 vars of field size 1, 2 and 3, the overall size must be a multiple of 3?
User avatar
LinearSpoon
Posts: 156
Joined: 29 Sep 2013, 22:55

Re: Questions about DllCall's

29 Jan 2015, 09:06

@jNizM
ULARGE_INTEGER is a union that is basically a UInt64. So in AHK, PULARGE_INTEGER is a "UInt64*", but AHK uses signed 64 bit integers. You'd probably be best off if you do what it says in the DllCall manual, ie: use Int64 and interpret negative values as very large values.
just me
Posts: 5397
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Questions about DllCall's

29 Jan 2015, 09:11

@evilC:
GetRawInputDeviceList(&dl, iCount)

  1. You're not passing a variable, but an address.
  2. I don't see any VarSetCapacity().
  3. If NULL, the number of devices are returned in *puiNumDevices.
just me
Posts: 5397
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Questions about DllCall's

29 Jan 2015, 09:16

evilC wrote:So if you have something that uses 3 vars of field size 1, 2 and 3, the overall size must be a multiple of 3?
Yes! But, to be clear, it depends on the type passed to the API function via DllCall(), not on the content of variables.
just me
Posts: 5397
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Questions about DllCall's

29 Jan 2015, 09:19

evilC wrote:I thought if I wanted to retrieve info out, I had to pass an address?
Are you talking about the DllCall() or the AHK function call?
User avatar
jNizM
Posts: 2317
Joined: 30 Sep 2013, 01:33
GitHub: jNizM
Contact:

Re: Questions about DllCall's

29 Jan 2015, 09:19

@LinearSpoon
I ask me why so many scripts exists with UInt64* / UInt64P
[AHK] 1.1.28.02 x64 Unicode | [WIN] 10 Pro (Version 1803) x64 | [GitHub] Profile
Donations are appreciated if I could help you
User avatar
evilC
Posts: 4183
Joined: 27 Feb 2014, 12:30

Re: Questions about DllCall's

29 Jan 2015, 09:22

just me wrote:
evilC wrote:I thought if I wanted to retrieve info out, I had to pass an address?
Are you talking about the DllCall() or the AHK function call?

The AHK function call.

The msgbox inside the function msgbox % "IN: " NumGet(pRawInputDeviceList, 2, "Uint") is the same as the one outside the function msgbox % "OUT: " NumGet(dl, 2, "Uint"), and that parameter in the function is specified as ByRef, so why do I get a different result outside than in?
just me
Posts: 5397
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Questions about DllCall's

29 Jan 2015, 09:26

@jNizM: You may write UInt64P, but AHK will take the result as a signed value in either case.
User avatar
evilC
Posts: 4183
Joined: 27 Feb 2014, 12:30

Re: Questions about DllCall's

29 Jan 2015, 09:47

OK, I think i begin to understand what is going on.

I passed in an uninitialzed var (Which I guess was assumed to be 0 by the code), which set the DLLCall to the other mode (where pRawInputDeviceList does not get set)

The fact that I was getting a value in the "IN: " msgbox is just coincidence or a factor of how I was (possibly mis-) using NumGet

Return to “Ask For Help”

Who is online

Users browsing this forum: havox, Siskin and 5 guests