The Cost and Complexity of Cgo
cockroachlabs.com
cockroachlabs.com
Code here: https://github.com/lazyfunctor/pymosaic
Edit: Added last line
I suspect that it is going to ultimately be your core problem. Even if you make it work with specific versions or specific modules, it'll always be fragile.
Like many modern languages that embed an event loop into themselves one way or another, the Go runtime expects to fully own the target process. It makes it difficult to play well with others, because the "default" C-based runtime provides so few guarantees that it's difficult for two otherwise C-compatible runtimes to "play nice" with each other. It's part of why the JVM and .Net are so interesting for cross-language development; the VM provides a richer, better-specified "base layer" that multiple languages can use, enabling much easier interop.
It's a death-by-a-thousand-cuts sort of thing; hypothetically nothing really prevents this, but in reality you're probably not going to want to take the time to make it work which may very well involve custom modifications of either runtime, when you should probably just go ahead and set up some RPC connections. (JSON's a nice default to prototype quickly, but depending on your needs you may want something like protocol buffers or the half-a-dozen competing libraries.)
If your library can be used completely with you managing the memory, you can use Go's allocator. E.g. libopus:
size := C.opus_encoder_get_size(C.int(channels))
mem := make([]byte, size)
p := (*C.OpusEncoder)(unsafe.Pointer(&enc.mem[0]))
This way, all memory is on the Go heap.Not every C library will support this, but those who do make CGo a lot more bearable.