Notes on cgo
Referencing c from go.
import “C” imports the C namespace into go, the comment just above this statement is treated as C.
Everything you exported from c library is available in the C namespace.
Building code is as easy as
Accessing standard types are easy as
C.int. For complex types, prepend the type name with an underscore at end – e.g
Pointers and memory operations
Go provides an
unsafe module. Go’s GC cannot manage the memory allocated in C code, you should call
free is defined in
<stdlib.h> ensure that this library is imported) to deallocate. There are some special functions which convert Go types to C types and vice versa. (lifted from cgo documentation)
// Go string to C string // The C string is allocated in the C heap using malloc. // It is the caller's responsibility to arrange for it to be // freed, such as by calling C.free (be sure to include stdlib.h // if C.free is needed). func C.CString(string) *C.char // C string to Go string func C.GoString(*C.char) string // C string, length to Go string func C.GoStringN(*C.char, C.int) string // C pointer, length to Go byte func C.GoBytes(unsafe.Pointer, C.int) byte
Accessing complex objects
Accessing structs from Go
You can also pass pointers
Accessing Unions : No native counterpart, instead of converting it to a type, go treats them as a block of memory represented as byte array. Accessing data is done by casting unsafe.Pointer
Compiler flags can be set using the
#cgo directive. (
In many cases using cgo breaks the portability of your app, use build constraints to specify compatibility in source. Build constraints are comments which begin with
Now, build comment must appear before package clause and should be followed by a blank line To restrict building just to Linux with cgo,
These are evaluated as
OR of each constraint so the above line becomes
(linux AND cgo) OR (NOT darwin), also multiple build tags can be embedded in file.
There are other methods to restrict builds, see references.