Common Patterns

Cgo common patterns #

C backed array to Go slice #

The following example shows how one may create a slice from a C backed array, without copying. A caveat of this approach is that either you must know the length of the underlying array beforehand, or specify a very large value as the length (e.g. 1 << 30).

package main

// char* get_c_array(void) {
//   char* arr = "hello";
//   return arr;
// }
import "C"
import (
	"fmt"
	"unsafe"
)

func main() {
	cbuf := C.get_c_array()
	//     cast to byte slice               set len and cap
	buf := (*[5]byte)(unsafe.Pointer(cbuf))[:5:5]
	fmt.Printf("from c: %s\n", buf)
}

Go backed slice to C array #

The following example shows how you can pass a slice allocated using Go to a C function. The example uses a zero-terminated string where the length is implicit, but one may pass the length of the slice as well.

package main

// #include <stdio.h>
// void print_go_slice(char *arr) {
//   printf("from go: %s\n", arr);
// }
import "C"
import "unsafe"

func main() {
	buf := []byte("hello\x00")
	C.print_go_slice((*C.char)(unsafe.Pointer(&buf[0])))
}