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)
Questions about DllCall's
Questions about DllCall's
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Re: Questions about DllCall's
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.
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.
Re: Questions about DllCall's
Ahh ok.. Thx for Info RHCP
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Re: Questions about DllCall's
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
Re: Questions about DllCall's
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:
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)
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
UINT WINAPI GetRawInputData(
_In_ HRAWINPUT hRawInput,
_In_ UINT uiCommand,
_Out_opt_ LPVOID pData,
_Inout_ PUINT pcbSize,
_In_ UINT cbSizeHeader
);
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
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)
}
Re: Questions about DllCall's
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:
So I open visual studio and insert in:
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?
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
UINT WINAPI GetRawInputDeviceList(
_Out_opt_ PRAWINPUTDEVICELIST pRawInputDeviceList,
_Inout_ PUINT puiNumDevices,
_In_ UINT cbSize // The size of a RAWINPUTDEVICELIST structure, in bytes.
);
typedef struct tagRAWINPUTDEVICELIST {
HANDLE hDevice;
DWORD dwType;
} RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST;
Code: Select all
size = sizeof(RAWINPUTDEVICELIST);
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?
Re: Questions about DllCall's
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.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?)
Re: Questions about DllCall's
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
What should I use or which one should I prefer?
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
VarSetCapacity(name, size, 0)
DllCall("xxx.dll", "UInt64", &name) ;Int64* or something else
NumGet(name, 0, "UInt64) ;Int64* or something else
Last edited by jNizM on 29 Jan 2015, 09:00, edited 3 times in total.
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Re: Questions about DllCall's
Aagh! I cannot understand what is going wrong in this code.
Why is the OUT: msgbox not the same as IN: ?
Why is the OUT: msgbox not the same as IN: ?
Code: Select all
#singleinstance force
global SIZE_RAWINPUTDEVICELIST := ps(2)
GetRawInputDeviceList(&dl, iCount)
msgbox % "OUT: " NumGet(dl, 2, "Uint")
return
ps(c := 1){
return c * A_PtrSize
}
GetRawInputDeviceList(ByRef pRawInputDeviceList, ByRef iCount){
;Get the device count
r := DllCall("GetRawInputDeviceList", "Ptr", pRawInputDeviceList, "UInt*", iCount, "UInt", ps(2) )
msgbox % "IN: " NumGet(pRawInputDeviceList, 2, "Uint")
;Check for error
If (r = -1) Or ErrorLevel {
ErrorLevel = GetRawInputDeviceList call failed.`nReturn value: %r%`nErrorLevel: %ErrorLevel%`nLine: %A_LineNumber%`nLast Error: %A_LastError%
Return -1
} Else Return iCount
}
Re: Questions about DllCall's
That's really complicated stuff. Let me try to explain this simple sample:evilC wrote:Also, I am not quite sure I get how to work out correct size.
Code: Select all
typedef struct tagRAWINPUTDEVICELIST {
HANDLE hDevice;
DWORD dwType;
} RAWINPUTDEVICELIST, *PRAWINPUTDEVICELIST;
32-bit 64-bit
HANDLE pointer-sized type A_PtrSize : 4 bytes 8 bytes
DWORD double word (2 * 2) : 4 bytes 4 bytes
Padding* 0 bytes 4 bytes
---------- -----------
8 bytes 16 bytes
* Per default, the whole length of a structure has to be a multiple of the maximum field size.
This can be overwritten by the developer!!!
32-bit: maximum size = 4, length = 8 , no padding needed
64-bit: maximum size = 8, length = 12 , 4 bytes needed for a multiple of 8
Whenever you need to pass a buffer to be filled by the API function, you have to pass its address using &Buffer.A large part of my problem is knowing when to use & and ByRef.
Re: Questions about DllCall's
"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?
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?
- LinearSpoon
- Posts: 156
- Joined: 29 Sep 2013, 22:55
Re: Questions about DllCall's
@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.
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.
Re: Questions about DllCall's
@evilC:
GetRawInputDeviceList(&dl, iCount)
GetRawInputDeviceList(&dl, iCount)
- You're not passing a variable, but an address.
- I don't see any VarSetCapacity().
- If NULL, the number of devices are returned in *puiNumDevices.
Re: Questions about DllCall's
I thought if I wanted to retrieve info out, I had to pass an address?
How come IN: reports a value OK if I needed to set capacity etc?
How come IN: reports a value OK if I needed to set capacity etc?
Re: Questions about DllCall's
Yes! But, to be clear, it depends on the type passed to the API function via DllCall(), not on the content of variables.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?
Re: Questions about DllCall's
Are you talking about the DllCall() or the AHK function call?evilC wrote:I thought if I wanted to retrieve info out, I had to pass an address?
Re: Questions about DllCall's
@LinearSpoon
I ask me why so many scripts exists with UInt64* / UInt64P
I ask me why so many scripts exists with UInt64* / UInt64P
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
Re: Questions about DllCall's
The AHK function call.just me wrote:Are you talking about the DllCall() or the AHK function call?evilC wrote:I thought if I wanted to retrieve info out, I had to pass an address?
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?
Re: Questions about DllCall's
@jNizM: You may write UInt64P, but AHK will take the result as a signed value in either case.
Re: Questions about DllCall's
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
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
Who is online
Users browsing this forum: Aqualest, Bing [Bot] and 364 guests