Convert python to AHK - 3 byte units

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Convert python to AHK - 3 byte units

24 Jun 2021, 13:55

My brain is having trouble converting this to AHK today.

Code: Select all

header = bytearray(12)
# API Version:
header[0] = 0
header[1] = 0
header[2] = 0
header[3] = 2 # docs say current apps should just use 2 here
# Reference ID:
header[4] = (refid >> 24) & 0xff
header[5] = (refid >> 16) & 0xff
header[6] = (refid >> 8) & 0xff
header[7] = (refid >> 0) & 0xff
# Message size:
header[8] = (requestLength >> 24) & 0xff
header[9] = (requestLength >> 16) & 0xff
header[10] = (requestLength >> 8) & 0xff
header[11] = (requestLength >> 0) & 0xff

# Then later on, extracting the same offsets from the same structure type
# Version number
version = ((data[0]) << 24) + ((data[1]) << 16) + ((data[2]) << 8) + ((data[3]) << 0)
# Reference ID
reference = ((data[4]) << 24) + ((data[5]) << 16) + ((data[6]) << 8) + ((data[7]) << 0)
# Message size - this tells us exactly how much data to receive for the response
responseSize = ((data[8]) << 24) + ((data[9]) << 16) + ((data[10]) << 8) + ((data[11]) << 0)
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Convert python to AHK - 3 byte units

24 Jun 2021, 14:06

Code: Select all

VarSetCapacity(header, 12)
; API Version:
NumPut(0, header, 0, "UChar")
NumPut(0, header, 1, "UChar")
NumPut(0, header, 2, "UChar")
NumPut(2, header, 3, "UChar") ; docs say current apps should just use 2 here
; Reference ID:
NumPut((refid >> 24) & 0xff, header, 4, "UChar")
NumPut((refid >> 16) & 0xff, header, 5, "UChar")
NumPut((refid >> 8) & 0xff, header, 6, "UChar")
NumPut((refid >> 0) & 0xff, header, 7, "UChar")
; Message size:
NumPut((requestLength >> 24) & 0xff, header, 8, "UChar")
NumPut((requestLength >> 16) & 0xff, header, 9, "UChar")
NumPut((requestLength >> 8) & 0xff, header, 10, "UChar")
NumPut((requestLength >> 0) & 0xff, header, 11, "UChar")
the other part is the same except with NumGet instead
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Convert python to AHK - 3 byte units

24 Jun 2021, 15:00

Ah ok. I wasn't thinking that it would be that literal of a translation. For some reason I thought python was making it harder than it needed to be.

Can you give a brief explanation why it would be "UChar"?
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Convert python to AHK - 3 byte units

24 Jun 2021, 15:05

https://www.autohotkey.com/docs/commands/DllCall.htm#types
Char An 8-bit integer, whose range is -128 (-0x80) to 127 (0x7F). An unsigned character (UChar) can be used with functions that expect a BYTE.
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Convert python to AHK - 3 byte units

24 Jun 2021, 15:18

Excellent, thank you very much!
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: Convert python to AHK - 3 byte units

25 Jun 2021, 05:43

kczx3 wrote:
24 Jun 2021, 15:00
For some reason I thought python was making it harder than it needed to be.
I suppose the first 4 bytes can be set with NumPut(0x02000000, header, 0, "UInt").

You could similarly put refid and requestLength with a single call each, but you would need to reverse the byte order of each value first, since x86 is natively little-endian (least significant byte first) and header is apparently big-endian (most significant byte first). I suppose either of these would do it:

Code: Select all

NumPut(((refid >> 24) & 0xff) <<  0
     | ((refid >> 16) & 0xff) <<  8
     | ((refid >>  8) & 0xff) << 16
     | ((refid >>  0) & 0xff) << 24, header, 4, "UInt")

Code: Select all

NumPut((refid & 0xff000000) >> 24
     | (refid & 0x00ff0000) >>  8
     | (refid & 0x0000ff00) <<  8
     | (refid & 0x000000ff) << 24, header, 4, "UInt")
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Convert python to AHK - 3 byte units

25 Jun 2021, 09:14

@lexikos neat, thanks for the alternative options! Yes, the API I am dealing with accepts a header that is three 4-byte numbers in MSB order over a socket. After sending the header, I send the payload and the server then responds with a similar header structure to indicate how large the actual response payload is. Thanks both for your help and explanations.

The C# code they have as an example:

Code: Select all

byte[] xmlmessage = ...;
byte[] header = new byte[12];
// API Version:
header[0] = 0;
header[1] = 0;
header[2] = 0;
header[3] = 2;
// Reference ID:
header[4] = (byte)((refid >> 24) & 0xff);
header[5] = (byte)((refid >> 16) & 0xff);
header[6] = (byte)((refid >> 8) & 0xff);
header[7] = (byte)((refid >> 0) & 0xff);
// Message size:
header[8] = (byte)((xmlmessage.Length >> 24) & 0xff);
header[9] = (byte)((xmlmessage.Length >> 16) & 0xff);
haeder[10] = (byte)((xmlmessage.Length >> 8) & 0xff);
header[11] = (byte)((xmlmessage.Length >> 0) & 0xff);
NetworkStream stream = client.GetStream();
stream.Write( header, 0, header.Length );
stream.Write( xmlmessage, 0, xmlmessage.Length );

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: No registered users and 328 guests