AWESOME GO — #4

Build and Use Go Packages as C Libraries

Minh-Phuc Tran
The Startup
Published in
2 min readOct 21, 2019

--

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)))
}

--

--

Minh-Phuc Tran
The Startup

Software Engineer. Documenting my journey at 𝐩𝐡𝐮𝐜𝐭𝐦𝟗𝟕.𝐜𝐨𝐦