Go Fil C et Go dans toutes les directions

Exemple

Appeler le code C de Go

``````package main

/*
// Everything in comments above the import "C" is C code and will be compiles with the GCC.
// Make sure you have a GCC installed.

int addInC(int a, int b) {
return a + b;
}
*/
import "C"
import "fmt"

func main() {
a := 3
b := 5

fmt.Println("Add in C:", a, "+", b, "=", int(c))
}
``````

Code d'appel de C de C

``````package main

/*
static inline int multiplyInGo(int a, int b) {
return go_multiply(a, b);
}
*/
import "C"
import (
"fmt"
)

func main() {
a := 3
b := 5

c := C.multiplyInGo(C.int(a), C.int(b))

fmt.Println("multiplyInGo:", a, "*", b, "=", int(c))
}

//export go_multiply
func go_multiply(a C.int, b C.int) C.int {
return a * b
}
``````

Traiter les pointeurs de fonction

``````package main

/*
int go_multiply(int a, int b);

typedef int (*multiply_f)(int a, int b);
multiply_f multiply;

static inline init() {
multiply = go_multiply;
}

static inline int multiplyWithFp(int a, int b) {
return multiply(a, b);
}
*/
import "C"
import (
"fmt"
)

func main() {
a := 3
b := 5
C.init(); // OR:
C.multiply = C.multiply_f(go_multiply);

c := C.multiplyWithFp(C.int(a), C.int(b))

fmt.Println("multiplyInGo:", a, "+", b, "=", int(c))
}

//export go_multiply
func go_multiply(a C.int, b C.int) C.int {
return a * b
}
``````

Types de conversion, structures d'accès et arithmétique de pointeur

De la documentation officielle Go:

``````// 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

// Go []byte slice to C array
// The C array 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.CBytes([]byte) unsafe.Pointer

// C string to Go string
func C.GoString(*C.char) string

// C data with explicit length to Go string
func C.GoStringN(*C.char, C.int) string

// C data with explicit length to Go []byte
func C.GoBytes(unsafe.Pointer, C.int) []byte
``````

Comment l'utiliser:

``````func go_handleData(data *C.uint8_t, length C.uint8_t) []byte {
return C.GoBytes(unsafe.Pointer(data), C.int(length))
}

// ...

goByteSlice := []byte {1, 2, 3}
goUnsafePointer := C.CBytes(goByteSlice)
cPointer := (*C.uint8_t)(goUnsafePointer)

// ...