While using GetRawInputData, I've stumbled upon an issue where the value of UsButtonFlags is apparently placed inside UsButtonData.
After looking at the code, I noticed the Pad_cgo_0 field and got to read a bit about the beautiful world of field alignment in C. I still don't know much about it but here's what worked in my case:
type MYRAWMOUSE struct {
UsFlags uint16
Pad_cgo_0 [2]byte
UsButtonFlags uint16
UsButtonData uint16
UlRawButtons uint32
LLastX int32
LLastY int32
UlExtraInformation uint32
}
By just moving that padding above UsButtonFlags it seems to work just fine, even for the info in LLastX and LLastY.
I was wondering about creating a PR but then noticed this might work differently depending on the target architecture. Can you please give me your thoughts on this? Is it safe to move that padding field, or will I have to look out for its position depending on my compiler target?
EDIT:
I did some more investigation on this and here's an interesting read on the subject: http://www.catb.org/esr/structure-packing/
I've also checked the paddings using this code:
/*
#include <windows.h>
*/
import "C"
import (
"github.com/davecgh/go-spew/spew"
)
func main() {
var test C.RAWMOUSE
spew.Dump(test)
}
Built for both 32bit and 64bit Windows:
set GOARCH=386 && go build -o ./build/Debug/test_offset_386.exe ./cmd/testoffset
set GOARCH=amd64 && go build -o ./build/Debug/test_offset_amd64.exe ./cmd/testoffset
Here's the output for 32bit:
$ ./build/Debug/test_offset_386.exe
(main._Ctype_struct_tagRAWMOUSE) {
usFlags: (main._Ctype_ushort) 0,
_: ([2]uint8) (len=2 cap=2) {
00000000 00 00 |..|
},
anon0: ([4]uint8) (len=4 cap=4) {
00000000 00 00 00 00 |....|
},
ulRawButtons: (main._Ctype_ulong) 0,
lLastX: (main._Ctype_long) 0,
lLastY: (main._Ctype_long) 0,
ulExtraInformation: (main._Ctype_ulong) 0
}
Here's the output for 64bit:
$ ./build/Debug/test_offset_amd64.exe
(main._Ctype_struct_tagRAWMOUSE) {
usFlags: (main._Ctype_ushort) 0,
_: ([2]uint8) (len=2 cap=2) {
00000000 00 00 |..|
},
anon0: ([4]uint8) (len=4 cap=4) {
00000000 00 00 00 00 |....|
},
ulRawButtons: (main._Ctype_ulong) 0,
lLastX: (main._Ctype_long) 0,
lLastY: (main._Ctype_long) 0,
ulExtraInformation: (main._Ctype_ulong) 0
}
You might need to check the RAWMOUSE struct and the Windows data type docs to make some sense of the above output.
The output is pretty much the same and the padding is set above the usButtonFlags+usButtonData inner struct. Maybe I need an actual 32bit machine for it to be different (not sure).
I wonder if the current Golang structure in this repo is prepared for 32bit builds since the commit was made in July 2012, or if this has been a bug all along 🤔
While using
GetRawInputData, I've stumbled upon an issue where the value ofUsButtonFlagsis apparently placed insideUsButtonData.After looking at the code, I noticed the
Pad_cgo_0field and got to read a bit about the beautiful world of field alignment in C. I still don't know much about it but here's what worked in my case:By just moving that padding above
UsButtonFlagsit seems to work just fine, even for the info inLLastXandLLastY.I was wondering about creating a PR but then noticed this might work differently depending on the target architecture. Can you please give me your thoughts on this? Is it safe to move that padding field, or will I have to look out for its position depending on my compiler target?
EDIT:
I did some more investigation on this and here's an interesting read on the subject: http://www.catb.org/esr/structure-packing/
I've also checked the paddings using this code:
Built for both 32bit and 64bit Windows:
Here's the output for 32bit:
$ ./build/Debug/test_offset_386.exe (main._Ctype_struct_tagRAWMOUSE) { usFlags: (main._Ctype_ushort) 0, _: ([2]uint8) (len=2 cap=2) { 00000000 00 00 |..| }, anon0: ([4]uint8) (len=4 cap=4) { 00000000 00 00 00 00 |....| }, ulRawButtons: (main._Ctype_ulong) 0, lLastX: (main._Ctype_long) 0, lLastY: (main._Ctype_long) 0, ulExtraInformation: (main._Ctype_ulong) 0 }Here's the output for 64bit:
$ ./build/Debug/test_offset_amd64.exe (main._Ctype_struct_tagRAWMOUSE) { usFlags: (main._Ctype_ushort) 0, _: ([2]uint8) (len=2 cap=2) { 00000000 00 00 |..| }, anon0: ([4]uint8) (len=4 cap=4) { 00000000 00 00 00 00 |....| }, ulRawButtons: (main._Ctype_ulong) 0, lLastX: (main._Ctype_long) 0, lLastY: (main._Ctype_long) 0, ulExtraInformation: (main._Ctype_ulong) 0 }You might need to check the RAWMOUSE struct and the Windows data type docs to make some sense of the above output.
The output is pretty much the same and the padding is set above the
usButtonFlags+usButtonDatainner struct. Maybe I need an actual 32bit machine for it to be different (not sure).I wonder if the current Golang structure in this repo is prepared for 32bit builds since the commit was made in July 2012, or if this has been a bug all along 🤔