Page 2 of 3

Re: Passing structure to function

Posted: 30 Dec 2018, 16:36
by jeeswg
- Can we have a summary of the situation, someone?
- UInt64 to pass an 8-byte value.
- UInt64* or UInt64P (essentially equivalent to using Ptr) would typically be used to create a variable containing a specific value. It does multiple things in one e.g. (the equivalent of) VarSetCapacity and NumGet, that using Ptr wouldn't do. Similarly Ptr v. Str, Str does (the equivalent of) VarSetCapacity -1.
- I had thought that it might be useful to have a 'third way', some shorthand to specify an address, and read and pass 8 bytes of data as a value. I wondered if there was any precedent for this. [EDIT: E.g. 'UInt64X' or 'UInt64V', you specify the address where 8 bytes of data start, and AHK reads the 8 bytes of data, as NumGet would do, as a UInt64 value, and passes the value.]
- Perhaps it's working in AutoIt because the number is stored as 8 bytes of data, and you're passing a pointer to the number, i.e. they are interchangeable, whereas in AutoHotkey things are stored as either/both a string or a number.
- Anyhow please correct/expand upon what I've said. Thanks.

- Also, I'd been wondering if you could put all of the DllCall parameters into a struct, and call it.
DllCall directly on a struct - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=60498

Re: Passing structure to function

Posted: 03 Jan 2019, 12:23
by Helgef
helgef2018 wrote:Next year, I will write a function for this.
:arrow: github.

I wish you all a great 2019, cheers.

Re: Passing structure to function

Posted: 03 Jan 2019, 14:42
by malcev
Helgef, Can You convert your function for ahk v1?
Thank You!

Re: Passing structure to function

Posted: 03 Jan 2019, 15:11
by jeeswg
- Hello Helgef. I looked at your dllcall_struct function, but can you clarify what it does? Are you essentially creating a new parameter type cf. Int / Ptr / Int* / Ptr*, similar to the idea I mentioned above with 'UInt64X'.
- [EDIT:] Another solution instead of a 'UInt64X' type etc, would be a MakeUInt64 function, that combines two Int-sized values (4 bytes) into one Int64-sized value (8 bytes). E.g. AutoHotkey_H has a MAKEWPARAM function to make a UPtr.
AutoHotkey_H New Features
https://hotkeyit.github.io/v2/docs/AHKH_Features.htm
- Also, any ideas for my one big struct idea. Thanks.
DllCall directly on a struct - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=60498

Re: Passing structure to function

Posted: 04 Jan 2019, 03:33
by Helgef
@ malcev, that really doesn't interest me, if you make an effort, I will help you if you get stuck.
jeeswg wrote: can you clarify what it does?
Hello. The readme explains what it does, how to use it and how it works (assuming the reader knows how to pass parameters to dllcall).
UInt64X
If you want a short hand for dereferencing a pointer I do not see why it would be limited to int64. I do not see how it is related to this topic.

Cheers.

Re: Passing structure to function

Posted: 04 Jan 2019, 06:04
by jeeswg
- I looked at your dllcall_struct function and readme, but can you clarify what it does?
- You could add a concrete example to the intro, e.g. WindowFromPoint called via DllCall and by your custom function.
- (The reason things like classes are so obscure to almost all AHK users, including me until I spent hours on it and asked many questions, is people don't go that extra step to make it understandable. The end result is that virtually nobody uses them or feels safe using them.)

- Re. related: seriously? AFAICS this thread boils down to: I would like to pass an 8-byte value (composed of 2 4-byte values), using its address, but instead I must use bitwise logic to combine 2 4-bytes values into a value, and pass that. The AutoHotkey_H 'MakeXXX' functions make the combining easy, and recreating them is certainly easier than recreating DllCall. Or do you see things differently? Cheers.

Re: Passing structure to function

Posted: 04 Jan 2019, 11:42
by Helgef
You could add a concrete example to the intro
There is an example in the repo.
e.g. WindowFromPoint called via DllCall and by your custom function.

Code: Select all

varsetcapacity pt, size := 8	; set up struct as usual
numput 100, pt, 0, 'int'
numput 500, pt, 4, 'int'
msgbox dllcall_struct('WindowFromPoint', 'struct', [&pt, size], 'ptr') ; and pass it...

AFAICS this thread boils down to:
No it doesn't.
The AutoHotkey_H 'MakeXXX' functions make the combining easy, and recreating them is certainly easier than recreating DllCall
Those functions doesn't help you pass a struct by value except for special cases, if you already know how to do it. I didn't recreate DllCall, I wrapped it, so you can easily pass and fetch any struct by value. You set up the struct as usual, and pass it.

Cheers.

Re: Passing structure to function

Posted: 05 Jan 2019, 04:37
by malcev
Helgef wrote:
04 Jan 2019, 03:33
@ malcev, that really doesn't interest me, if you make an effort, I will help you if you get stuck.
It is easier for me to count padding of structure by myself than read about differences between ahk v2 and ahk v1 to convert Your function.
As I understand {char c;short s;} for x86 We have to pass without alignment:

Code: Select all

"int", c | (s << 8)
But for x64 with alignment:

Code: Select all

"int", c | (s << 16)

Re: Passing structure to function

Posted: 05 Jan 2019, 04:42
by Helgef
No it's "int", c | (s << 16) on both.

Re: Passing structure to function

Posted: 05 Jan 2019, 20:42
by malcev
Thank You. You are right!
Dont You know why this code works on autohotkey 32 bit with 32 bit dll, but it shows error 0xC0000005 on autohotkey 64 bit with 64 bit dll:

Code: Select all

width := 100
height := 100
cvsize := (height << 32) | width
pimg := DllCall("opencv_core2413.dll\cvCreateImage", "int64", cvsize, "int", IPL_DEPTH_8U := 8, "int", channels := 2, "Cdecl Ptr")
DllCall("opencv_core2413.dll\cvSet", "ptr", pimg, "double", 1, "double", 1, "double", 1, "double", 1, "ptr", 0, "Cdecl")
msgbox % errorlevel
N (any positive number): The function was called but it aborted with fatal exception number N (for example, 0xC0000005 means "access violation"). In such cases, the function returns a blank value (empty string), but any asterisk variables are still updated. An example of a fatal exception is dereferencing an invalid pointer such as NULL. Since a Cdecl function never produces the "An" error in the next paragraph, it may generate an exception when too few arguments are passed to it.
Here is 32 bit and 64 bit dll:
https://files.fm/u/m7subwa9

Re: Passing structure to function

Posted: 06 Jan 2019, 01:28
by YMP2
It works if the structure of double's is passed by reference. At least ErrorLevel is 0.

Re: Passing structure to function

Posted: 06 Jan 2019, 01:59
by Helgef
Helgef wrote:
29 Dec 2018, 15:28
struct d {double; double; ... double;} must be passed as "ptr", &d for x64 and "double", d1, ..., "double", dn for cdecl.

Re: Passing structure to function

Posted: 06 Jan 2019, 06:49
by malcev
YMP2, Helgef, Thank You. It works!

Re: Passing structure to function

Posted: 13 Jan 2019, 04:56
by malcev
Helgef wrote:
29 Dec 2018, 15:28
But struct S2 {char c1;short s;char c2;} would need to be passed as "ptr", &S2 for x64
Why it should not be passed for x64 as "int64", c1 | (s << 16) | (c2 << 32)?
The size of this structure is 64bit.

Re: Passing structure to function

Posted: 13 Jan 2019, 05:16
by Helgef
No the size is 48 bits.

Re: Passing structure to function

Posted: 13 Jan 2019, 05:27
by malcev
I thought that when we pass copy of structure and add note that it is int64, null bits will be added to the end automatically.
I was wrong?

Re: Passing structure to function

Posted: 13 Jan 2019, 05:33
by Helgef
The upper bits of "int64", c1 | (s << 16) | (c2 << 32) will be zero, but that is not the point, the point is that the size of the structure is not,
8, 16, 32, or 64 bits
hence it must be,
passed as a pointer to memory allocated by the caller.
Src .

Cheers.

Re: Passing structure to function

Posted: 19 Mar 2019, 08:14
by jeeswg
- I'm trying to summarise the logic of the dllcall_struct function:
- To pass structs in 32-bit AHK, for stdcall functions, you're using repeated Ints.
- To pass structs in 64-bit AHK, for stdcall functions, you're passing the address of the struct (apart from for structs of size 1/2/4/8 bytes, aka 8/16/32/64 bits). For structs of all other sizes you are passing the address.
- Is this correct, or are there further nuances, perhaps cdecl functions are different. Thanks.

Re: Passing structure to function

Posted: 20 Mar 2019, 03:07
by Helgef
stdcall / cdecl doesn't apply to x64. For x64, all structs which are not of size,
8, 16, 32, or 64 bits
must be
passed as a pointer to memory allocated by the caller.
Otherwise they are passed in register / on the stack as appropriate.

On 32 bit, all structs are passed directly on the stack, for both stdcall and cdecl.

Cheers.

Re: Passing structure to function

Posted: 20 Mar 2019, 07:02
by jeeswg
- Thanks Helgef. In trying to get this script to work on AHK 64-bit, I passed a pointer to a 16-byte (128-bit) struct.
Magnification API - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=31748