Code: Select all
; Define an integer variable
intVar := 123
ptr := &intVar ; Get the address of the integer
MsgBox % Format("The address of the integer is: 0x{:X}", ptr)
Code: Select all
; Define an integer variable
intVar := 123
ptr := &intVar ; Get the address of the integer
MsgBox % Format("The address of the integer is: 0x{:X}", ptr)
Thank you for your response. I used AutoHotkey v1.1 before, and now I am learning AutoHotkey v2.0. I have noticed some differences in this regard. Therefore, I would like to confirm whether AutoHotkey v2.0 does not support obtaining the addresses of variables of integer and float types. From your reply, it seems that directly obtaining the addresses of integer and float variables is not supported now, is that correct?
lexikos wrote: ↑23 Mar 2024, 22:12ptr := &intVar never did "Get the address of the integer". It got the address of a string of digits. That is now achieved by StrPtr.
This and most (optimistically "all") other changes are explained in Changes from v1.1 to v2.0. Just search that page for "&var (address-of)".
I would still want to know "what do you need it for?" to provide more pointed advice. For instance, what to do if and when you actually need the address of an integer.
var is not a "string variable", but a variable that can contain anything, even if it currently contains a string. &var in v1 can return the address of a string even if the variable contained a number, and sometimes that is what you want; or it can return the address of an object, which is entirely a different thing.return wrote:Does this mean that "&var" is only suitable for string variables?
The "current" method is not to "copy them into a buffer and use NumGet", but to use bitwise-AND/OR and bit-shifting.iseahound wrote:The current method of getting signed shorts from an int is to copy them into a buffer and use NumGet.
Code: Select all
var:=-1
msgbox "Arithmetic bit shift right (>>)`t: " var<<48>>48 ; -1
msgbox "Logical bit shift right (>>>)`t: " var<<48>>>48 ; 65535 (0xFFFF)
Code: Select all
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
#define MAKELPARAM(l, h) ((LPARAM)(DWORD)MAKELONG(l, h))
Code: Select all
; ahk2.0
GET_X_LPARAM(lParam) {
return (buf:=buffer(16,0), numput("UShort",lParam&0xFFFF,buf), numGet(buf,"Short"))
}
GET_Y_LPARAM(lParam) {
return (buf:=buffer(16,0), numput("UShort",(lParam>>16)&0xFFFF,buf), numGet(buf,"Short"))
}
MAKELPARAM(l, h) {
return (buf:=buffer(32,0), numput("Short",l,"Short",h,buf), numGet(buf,"Ptr"))
}
loop {
switch (A_Index)
{
default: break
case 1: wLow := 1 ,wHigh := 2
case 2: wLow := -1 ,wHigh := 2
case 3: wLow := 1 ,wHigh := -2
case 4: wLow := -1 ,wHigh := -2
}
lpA:=MAKELPARAM(wLow, wHigh)
x:=GET_X_LPARAM(lpA)
y:=GET_Y_LPARAM(lpA)
lpB:=MAKELPARAM(x,y)
msgbox
(LTrim
A_Index "
" lpA "
" x "
" y "
" lpB
)
}
Code: Select all
; ahk2.0
GET_X_LPARAM(lParam) {
return (lParam&0xFFFF)<<48>>48
}
GET_Y_LPARAM(lParam) {
return ((lParam>>16)&0xFFFF)<<48>>48
}
MAKELPARAM(l, h) {
return (buf:=buffer(32,0), numput("Short",l,"Short",h,buf), numGet(buf,"Ptr"))
}
loop {
switch (A_Index)
{
default: break
case 1: wLow := 1 ,wHigh := 2
case 2: wLow := -1 ,wHigh := 2
case 3: wLow := 1 ,wHigh := -2
case 4: wLow := -1 ,wHigh := -2
}
lpA:=MAKELPARAM(wLow, wHigh)
x:=GET_X_LPARAM(lpA)
y:=GET_Y_LPARAM(lpA)
lpB:=MAKELPARAM(x,y)
msgbox
(LTrim
A_Index "
" lpA "
" x "
" y "
" lpB
)
}
Code: Select all
#Requires AutoHotkey v2 32-bit
MsgBox "Running " (A_PtrSize = 4 ? "32-bit" : "64-bit")
MsgBox 0xFFFF << 48 >> 48
Code: Select all
low_word := -1, high_word := -2, dword := MAKELPARAM(low_word, high_word)
MsgBox dword "`n" GET_Y_LPARAM(dword) "`n" GET_X_LPARAM(dword)
; SHORT and INT
GET_Y_LPARAM(lp) => ((lp&0xFFFFFFFF)<<32>>48)
GET_X_LPARAM(lp) => ((lp&0xFFFFFFFF)<<48>>48)
MAKELPARAM(l, h) => (l<<48>>>48)|(h<<48>>>32)
; USHORT and UINT
HIWORD(DWORD) => ((DWORD>>16)&0xFFFF)
LOWORD(DWORD) => (DWORD&0xFFFF)
MAKEWORD(LOWORD, HIWORD) => (HIWORD<<16)|(LOWORD&0xFFFF)
Code: Select all
msgbox format("{:016X}",0) ; 0000000000000000
msgbox format("{:016X}",16384) ; 0000000000004000
msgbox format("{:016X}",32767) ; 0000000000007FFF
msgbox format("{:016X}",-32768) ; FFFFFFFFFFFF8000
msgbox format("{:016X}",-16384) ; FFFFFFFFFFFFC000
msgbox format("{:016X}",-1) ; FFFFFFFFFFFFFFFF
Code: Select all
; Utilizing buffers.
GET_X_LPARAM(lParam) => (buf:=buffer(16,0), numput("UShort",lParam&0xFFFF,buf), numGet(buf,"Short"))
GET_Y_LPARAM(lParam) => (buf:=buffer(16,0), numput("UShort",(lParam>>16)&0xFFFF,buf), numGet(buf,"Short"))
MAKELPARAM(l, h) => (buf:=buffer(32,0), numput("Short",l,"Short",h,buf), numGet(buf,"Ptr"))
Code: Select all
; Utilizing bitwise shifting (recommended).
GET_X_LPARAM(lParam) => (lParam<<48>>48)
GET_Y_LPARAM(lParam) => (lParam<<32>>48)
MAKELPARAM(l, h) => (lp:=(l&0xFFFF)|((h&0xFFFF)<<16), A_PtrSize==8?lp:lp<<32>>32) ; (lp:=(l<<48>>>48)|(h<<48>>>32), A_PtrSize==8?lp:lp<<32>>32)
Code: Select all
loop {
switch (A_Index)
{
default: break
case 1: wLow := 0 ,wHigh := 0
case 2: wLow := -16384 ,wHigh := 16384
case 3: wLow := -1 ,wHigh := -32768
case 4: wLow := 16384 ,wHigh := -16384
case 5: wLow := -1 ,wHigh := -1
}
lpA:=MAKELPARAM(wLow, wHigh)
x:=GET_X_LPARAM(lpA)
y:=GET_Y_LPARAM(lpA)
lpB:=MAKELPARAM(x,y)
msgbox
(LTrim
A_Index "
" lpA "
" x "
" y "
" lpB
)
}
Code: Select all
loop 65536 {
i:=A_Index-1
wLow:=i
if (32767<wLow)
wLow-=65536
wHigh:=65535-i
if (32767<wHigh)
wHigh-=65536
lpA:=MAKELPARAM(wLow, wHigh)
x:=GET_X_LPARAM(lpA)
y:=GET_Y_LPARAM(lpA)
lpB:=MAKELPARAM(x,y)
if (wLow!==x || wHigh!==y || lpA!==lpB) {
msgbox "False"
ExitApp
}
}
msgbox "True"
iseahound wrote: ↑26 Mar 2024, 09:19I distinctly remember running into bugs with negative numbers when merging them as two integers side by side into an int64. It's possible the masking is an important step that I didn't use, as clearly shown above. If you think the masking is important, then just say so, otherwise I've clearly given the exact method I normally use. If masking isn't important, then I can show you bugs where this clearly fails.
In any case, you proved yourself that the exact method the C/C++ code uses to sign extend isn't based off the size of an integer buffer (apparently hard coded to 8 bytes in AHK) but rather it calls the sign extend assembly instruction via type casts.
I tend to avoid bit-magic that relies on the size of the underlying buffer, since it often makes no sense from a readability perspective. If you can confirm that using a size of 8 bytes is indeed safe and reccomended, then it wouldn't be out of the question to start encoding special numbers or bit wise transforms that need the number 8. For example, how can one rotate a 8x8 matrix of zeros and ones represented as a 64-bit integer? A meaningless question unless 32-bit ahk really uses 64-bit numbers w/o any underlying gotchas.
Code: Select all
#Requires AutoHotkey v2.0
#SingleInstance
GET_X_LPARAM(lParam) => (lParam<<48>>48)
GET_Y_LPARAM(lParam) => (lParam<<32>>48)
l:=-32768
h:=98322 ; Exceeding the range of a short (-32,768 ~ 32,767)
;---------------------------------------------------------------------------------------
; 64 bit 32 bit
msgbox A_Clipboard := format("{:016X}",l) ; FFFFFFFFFFFF8000 FFFFFFFFFFFF8000
msgbox A_Clipboard := format("{:016X}",h) ; 0000000000018012 0000000000018012
;--------------------------------------------------------------------------------------- 1. Using buffers.
lp:=0
buf:=buffer(32,0)
numput("Short",l,"Short",h,buf)
lp:=numGet(buf,"Ptr")
msgbox A_Clipboard := lp ; 2148696064 -2146271232
msgbox A_Clipboard := format("{:016X}",lp) ; 0000000080128000 FFFFFFFF80128000
x:=GET_X_LPARAM(lp)
y:=GET_Y_LPARAM(lp)
msgbox A_Clipboard := x ; -32768 -32768
msgbox A_Clipboard := format("{:016X}",x) ; FFFFFFFFFFFF8000 FFFFFFFFFFFF8000
msgbox A_Clipboard := y ; -32750 -32750
msgbox A_Clipboard := format("{:016X}",y) ; FFFFFFFFFFFF8012 FFFFFFFFFFFF8012
;--------------------------------------------------------------------------------------- 2. Using bitwise shifting without masking (incorrect example).
lp:=(l|(h<<16))
msgbox A_Clipboard := lp ; -32768 -32768
msgbox A_Clipboard := format("{:016X}",lp) ; FFFFFFFFFFFF8000 FFFFFFFFFFFF8000
x:=GET_X_LPARAM(lp)
y:=GET_Y_LPARAM(lp)
msgbox A_Clipboard := x ; -32768 -32768
msgbox A_Clipboard := format("{:016X}",x) ; FFFFFFFFFFFF8000 FFFFFFFFFFFF8000
msgbox A_Clipboard := y ; -1 -1
msgbox A_Clipboard := format("{:016X}",y) ; FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
;--------------------------------------------------------------------------------------- 3. Bitwise shifting.
lp:=((l&0xFFFF)|((h&0xFFFF)<<16))
msgbox A_Clipboard := lp ; 2148696064 2148696064
msgbox A_Clipboard := format("{:016X}",lp) ; 0000000080128000 0000000080128000
x:=GET_X_LPARAM(lp)
y:=GET_Y_LPARAM(lp)
msgbox A_Clipboard := x ; -32768 -32768
msgbox A_Clipboard := format("{:016X}",x) ; FFFFFFFFFFFF8000 FFFFFFFFFFFF8000
msgbox A_Clipboard := y ; -32750 -32750
msgbox A_Clipboard := format("{:016X}",y) ; FFFFFFFFFFFF8012 FFFFFFFFFFFF8012
;--------------------------------------------------------------------------------------- 4. Bitwise shifting (Ptr).
lp:=((l&0xFFFF)|((h&0xFFFF)<<16))
if (A_PtrSize!==8)
lp:=lp<<32>>32 ; Int64 to Int
msgbox A_Clipboard := lp ; 2148696064 -2146271232
msgbox A_Clipboard := format("{:016X}",lp) ; 0000000080128000 FFFFFFFF80128000
x:=GET_X_LPARAM(lp)
y:=GET_Y_LPARAM(lp)
msgbox A_Clipboard := x ; -32768 -32768
msgbox A_Clipboard := format("{:016X}",x) ; FFFFFFFFFFFF8000 FFFFFFFFFFFF8000
msgbox A_Clipboard := y ; -32750 -32750
msgbox A_Clipboard := format("{:016X}",y) ; FFFFFFFFFFFF8012 FFFFFFFFFFFF8012
Code: Select all
#Requires AutoHotkey v2.0
#SingleInstance
lp := 0x00000000FF00FF00
A(lParam) => (lParam<<48>>48)
B(lParam) => (buf:=buffer(16,0), numput("UShort",lParam,buf), numGet(buf,"Short"))
msgbox A(lp) "`n" B(lp)
;---------------------------------------------------------------------------------------
sleep 0
startA:=A_TickCount
loop 10000000
A(lp)
endA:=A_TickCount
sleep 0
startB:=A_TickCount
loop 10000000
B(lp)
endB:=A_TickCount
;---------------------------------------------------------------------------------------
msgbox endA-startA ; 3453ms
msgbox endB-startB ; 12750ms
Users browsing this forum: BlueHornet, Descolada, TAC109 and 18 guests