Passing structure to function

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Passing structure to function

30 Dec 2018, 16:36

- 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
Last edited by jeeswg on 03 Jan 2019, 12:48, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Passing structure to function

03 Jan 2019, 12:23

helgef2018 wrote:Next year, I will write a function for this.
:arrow: github.

I wish you all a great 2019, cheers.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Passing structure to function

03 Jan 2019, 14:42

Helgef, Can You convert your function for ahk v1?
Thank You!
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Passing structure to function

03 Jan 2019, 15:11

- 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
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Passing structure to function

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.
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.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Passing structure to function

04 Jan 2019, 06:04

- 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.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Passing structure to function

04 Jan 2019, 11:42

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.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Passing structure to function

05 Jan 2019, 04:37

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)
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Passing structure to function

05 Jan 2019, 04:42

No it's "int", c | (s << 16) on both.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Passing structure to function

05 Jan 2019, 20:42

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
YMP2
Posts: 48
Joined: 20 Apr 2014, 06:55

Re: Passing structure to function

06 Jan 2019, 01:28

It works if the structure of double's is passed by reference. At least ErrorLevel is 0.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Passing structure to function

06 Jan 2019, 01:59

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.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Passing structure to function

06 Jan 2019, 06:49

YMP2, Helgef, Thank You. It works!
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Passing structure to function

13 Jan 2019, 04:56

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.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Passing structure to function

13 Jan 2019, 05:16

No the size is 48 bits.
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: Passing structure to function

13 Jan 2019, 05:27

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?
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Passing structure to function

13 Jan 2019, 05:33

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.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Passing structure to function

19 Mar 2019, 08:14

- 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.
Last edited by jeeswg on 20 Mar 2019, 07:27, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: Passing structure to function

20 Mar 2019, 03:07

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.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: Passing structure to function

20 Mar 2019, 07:02

- 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
Last edited by jeeswg on 20 Mar 2019, 07:28, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: imstupidpleshelp, RussF, sbrady19 and 147 guests