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 golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.