Hello,
I've been coding up a Windows based application and hit a problem that I
sort of understand however not how to resolve.
The debug + panic is
TranslateMessage Msg: &win.Msg{Wnd:(win.HWnd)(0x5a0cdc), Message:0x113,
WParam:0x1, LParam:0, Time:0x28699637, Pt:win.Point{X:1174, Y:488}}
TranslateMessage CMsg:
&win._Ctype_struct_tagMSG{hwnd:(win._Ctype_HWND)(0x5a0cdc), message:0x113,
_:[4]uint8{0x0, 0x0, 0x0, 0x0}, wParam:0x1, lParam:0, time:0x28699637,
pt:win._Ctype_struct_tagPOINT{x:1174, y:488}, _:[4]uint8{0x0, 0x0, 0x0,
0x0}}
Size: SizeOf(*Msg) 48 = Sizeof(*CMsg) 48
panic: runtime error: cgo argument has Go pointer to Go pointer
goroutine 1 [running, locked to thread]:
win.TranslateMessage.func1(0xc0420760f0, 0x29)
C:/progs/ake_g/src/win/funcs.go:282 +0x59
win.TranslateMessage(0xc0420760f0, 0x0)
C:/progs/ake_g/src/win/funcs.go:282 +0x1da
ake.(*Platform).Poll(0xc0420760c0)
C:/progs/ake_g/src/ake/platform.go:84 +0x7c
ake.(*Application).Start(0xc042046420)
C:/progs/ake_g/src/ake/system.go:68 +0x10d
main.main()
C:/progs/ake_g/src/shooty/shooty.go:157 +0xc5
I have created a wrapped around the Windows TranslateMessage function. I am
passing in my version of the Msg structure (that I have recreated in Go)
which is then cast to C.MSG structure as constructed via cgo.
func TranslateMessage(msg *Msg) bool {
fmt.Printf("TranslateMessage Msg: %#v\n", msg)
c_msg := (*C.MSG)(unsafe.Pointer(msg))
fmt.Printf("TranslateMessage CMsg: %#v\n", c_msg)
fmt.Printf("Size: SizeOf(*Msg) %d = Sizeof(*CMsg) %d\n",
unsafe.Sizeof(*msg), unsafe.Sizeof(*c_msg))
rc := C.TranslateMessage(c_msg)
return rc != WinFalse
}
The debug shows that both these structures have the same memory layout and
are the same size (though the cgo version correctly has forced padding).
The C.TranslateMessage (generated by cgo) is
//line c:\progs\ake_g\src\win\funcs.go:274
func TranslateMessage(msg *Msg) bool {
fmt.Printf("Msg: %#v\n", msg)
c_msg := (*_Ctype_struct_tagMSG)(unsafe.Pointer(msg))
fmt.Printf("CMsg: %#v\n", c_msg)
fmt.Printf("Size: %d = %d\n", unsafe.Sizeof(*msg),
unsafe.Sizeof(*c_msg))
//line c:\progs\ake_g\src\win\funcs.go:281
//line c:\progs\ake_g\src\win\funcs.go:280
rc := func(_cgo0 *_Ctype_struct_tagMSG) _Ctype_WINBOOL {
//line c:\progs\ake_g\src\win\funcs.go:280
_cgoCheckPointer(_cgo0)
//line c:\progs\ake_g\src\win\funcs.go:280
return _Cfunc_TranslateMessage(_cgo0)
//line c:\progs\ake_g\src\win\funcs.go:280
}(c_msg)
//line c:\progs\ake_g\src\win\funcs.go:283
//line c:\progs\ake_g\src\win\funcs.go:282
return rc != WinFalse
}
I believe the error is that _cgoCheckPointer is scanning the _cgo0 variable
(ie c_msg, ie type *_Ctype_struct_tagMSG) and detecting the
hwnd:(win._Ctype_HWND)(0x5a0cdc) value 0x5a0cdc is a pointer to something
on the Go heap.
In reality this value is assigned by Windows and is actually the window
handle.
Initially I was just going to force my win.HWnd to be a uintptr (as
effectively its a handle). However the cgo code knows its actually an
opaque pointer and thus treats it as a real pointer (unsafe.Pointer). So I
think forcing my code to use a uintptr won't help. Also it seems that
general guidelines are to use unsafe.Pointer if its a pointer (or appears
to be).
This is the structure that cgo generates based on the window.h header file
type _Ctype_struct_tagMSG struct {
hwnd _Ctype_HWND
message _Ctype_UINT
_ [4]byte
wParam _Ctype_WPARAM
lParam _Ctype_LPARAM
time _Ctype_DWORD
pt _Ctype_struct_tagPOINT
_ [4]byte
}
type _Ctype_HWND *_Ctype_struct_HWND__
type _Ctype_struct_HWND__ struct {
unused _Ctype_int
}
Its also worth mentioning that even though the C header has HWND as a
struct HWND__* in reality the HWND can be align on a 2 byte boundary (ie
its not a real pointer/8 byte boundary).
I am running this with
go version go1.8.3 windows/amd64
Also go vet (not surprisingly) doesn't find any problems with my code
(mainly because this pointer/handle is runtime generated by Windows).
Does anyone have any suggestions about how to work around this (other than
creating a fake windows.h)?
The problem occurs roughly 5% of the time when I start my program.
Thanks
Phil
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.