I'm a relative newbie to go. I have been working a lot with cgo and building an interface to a C api. The C api uses a registered callback and a void*
cookie parameter to the callback.
Here is some code exemplifying my problem:
/*
void cb(void *cookie) {
callGo(cookie);
}
go_register_cb(void *ptr) {
register_cb(&cb, ptr);
}
*/
import "C"
and
import "C"
//export callGo
callGo(ptr unsafe.Pointer) {
x := (*MyStruct)(ptr)
x.doSomething()
}
func (x *MyStruct) Start() {
C.go_register_cb(unsafe.Pointer(x))
}
This code causes a runtime error about Go pointers to Go pointers.
I think I understand the basic implications of keeping Go pointer inside C-land, which is that the C-land reference will not be accounted for in the go garbage collector so C may end up using a stale reference.
The specific requirement that I cannot pass a Go pointer to a data-structure that itself contains a Go pointer is more puzzling. The only thing that makes sense to me is that pointers in Go may change value (that is, the address they point to) due to garbage collection. Is this the case?