Cgo is pretty awesome. But there are a lot of reasons you probably shouldn't use it. This is both why to think hard about that, and then some lessons learned from building a Cgo project and running it in production.
When and (Usually) When Not to Use it
Principal Systems Engineer
Nitro Software - Dublin
Co-Author: “Docker: Up and Running”
Why You Should Not Use Cgo
● Breaks a lot of Go’s awesome tooling
● Everyone loves C builds/compiles, right?
● Puts Go’s concurrency promise at risk
● Might break your static binary
● No cross compiling
● You get to manage C-allocated memory yourself
● Calls into C via Cgo are much slower than Go calls
When to Use Cgo
● There is no Go equivalent to a library you need/can’t write in Go
● Legacy code that needs a web frontend
● Proprietary libraries/SDKs
● Legacy business logic e.g. with no functional tests/hard to rewrite/replace
So many caveats, but Cgo is actually really good for what it is
How to Do It
● Be comfortable in C!
● Plan on having a Makefile—go build won’t cut it
● Wrap Cgo code into a package to help isolate it and its nasty build
● Ideally link to static C libraries or your install gets complicated
● Write C bridge functions when necessary (e.g. Cgo can’t call macros)
● Reduce calls back and forth between Go/C
● Work around any nasty typecasting in C—Go types are stronger
● Wrap any C functions you need to test in Go—can’t use Cgo in tests!
● Leverage Go’s defer to make sure you free memory
● Pass Go-allocated memory to C functions when possible