AWESOME GO — #4
Build and Use Go Packages as C Libraries
--
CGO is an official builtin feature of Go, it enables the creation of Go packages that reference to C libraries. But it isn’t just that, it is achievable in the opposite direction, too. It enables creation of C libraries from Go packages so that C code can reference to Go, which is mind-blowing.
How to
Build Go package as C shared library (or shared object)
Every Go main
package can be built as a C shared library.
$ go build -go build -buildmode c-shared -o <c-lib>.so <go-package>
Executing above command builds target Go main
package and all of its dependencies as a single C shared library, which can be distributed, installed and linked to every C application and applications in other programming languages that can reference C shared libraries (C++, Python, Javascript, etc).
Note: Output C shared libraries should be named in standard form lib*.so
.
Generate C header and export Go functions as C functions
Building a Go main
package as C shared library doesn’t automatically neither generate C header nor expose any Go function as C symbol. Developers have to explicitly indicate which Go functions to be exposed.
To export a Go function as a C symbol:
- Add comment
//export FuncName
on top of the Go function. - The Go code file containing the function has to
import "C"
. - The function must belong to
main
package. - The function signature must not include neither Go struct nor Go interface nor Go array nor variadic argument.
package main import "C"import (
"math/rand"
"time"
)//export cgoCurrentMillis
func cgoCurrentMillis() C.long {
return C.long(time.Now().Unix())
}//export cgoSeed
func cgoSeed(m C.long) {
rand.Seed(int64(m))
}//export cgoRandom
func cgoRandom(m C.int) C.int {
return C.int(rand.Intn(int(m)))
}