I’m integrating a c library into my go program, and one of the functions I have to use have a callback interface. As is common with these, the function in question also takes a pointer, that it will pass you as a parameter when it calls the callback.
The code looks a little something like this. The wrapping has to do with the fact that this was the only way for it to accept the types, as directly passing the go callback to the c function complained that the callback didn’t match type *[0]byte.
/*
extern bool goCallback(void*);
static bool callback(void* data)
{
return goCallback(data);
}
static WrapCall(void* data)
{
return callRelevantCFunction(callback, data);
}
*/
import "C"
func goCallback(p unsafe.Pointer) {
data := (*MyObjectType)(p)
//do things
}
func main() {
obj := &MyObjectType{}
C.WrapCall(unsafe.Pointer(obj))
}
My understanding is that under normal circumstances if obj contains other go pointers, it would be unsafe to deference those pointers. They might invalidated if the GC decides to move these the objects pointed at, or if a reference is dropped clean them up.
Unfortunately, the data needed by the callback fairly large with many nested go objects.
In order to avoid a large amount of work refactoring this object so the data lives in C memory, would it suffice to disable the GC for the duration of the C function call that may invoke the callback?