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 importCGOFILES=foo.go to your Makefile#cgo preprocessor instructions to set C defines and linker flags
package 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.Pointertypedefs are available under their own namestructs are available with a struct_ prefix, e.g. struct foo → C.struct_foo, same goes for unions and enumsC 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: