Go & cgo: integrating existing C code with Go
Andreas Krennmair <ak@synflood.at>
Golang User Group Berlin
Twitter: @der_ak
Andreas Krennmair <ak@synflood.at>
Golang User Group Berlin
Twitter: @der_ak
import "C"
#include <foo.h>
) prior to the import
CGOFILES=foo.go
to your Makefile#cgo
preprocessor instructions to set C defines and linker flagspackage pwnam /* #include <sys/types.h> #include <pwd.h> #include <stdlib.h> */ import ( "C" ; "unsafe" ) type Passwd struct { Uid uint32 ; Gid uint32 ; Dir string ; Shell string } func Getpwnam(name string) *Passwd { cname := C.CString(name) defer C.free(unsafe.Pointer(cname)) cpw := C.getpwnam(cname) return &Passwd{ Uid: uint32(cpw.pw_uid), Gid: uint32(cpw.pw_uid), Dir: C.GoString(cpw.pw_dir), Shell: C.GoString(cpw.pw_shell)} }
CGO_LDFLAGS
to Makefile#cgo
directive (preferred)#cgo LDFLAGS:
package pcap /* #cgo LDFLAGS: -lpcap #include <stdlib.h> #include <pcap.h> */ import "C"
#cgo pkg-config:
package stfl /* #cgo pkg-config: stfl #cgo LDFLAGS: -lncursesw #include <stdlib.h> #include <stfl.h> */ import "C"
C
pseudo-packageint
→ C.int
, unsigned short
→ C.ushort
, etc.void *
is unsafe.Pointer
typedef
s are available under their own namestruct
s are available with a struct_
prefix, e.g. struct foo
→ C.struct_foo
, same goes for union
s and enum
sC
package contains conversion functions to convert Go to C strings and vice versavoid *
) to []byte
// Go string to C string; result must be freed with C.free 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
//export <function-name>
package foo /* extern void myprint(int i); void dofoo(void) { int i; for (i=0;i<10;i++) { myprint(i); } } */ import "C"
//export myprint func myprint(i C.int) { fmt.Printf("i = %v\n", uint32(i)) } func DoFoo() { C.dofoo() }
Useful Links: