Lab 02: CGO Interop
Overview
Step 1: Basic CGO — C from Go
package main
// CGO preamble: C code embedded in Go source
/*
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
// Simple C function
int add(int a, int b) {
return a + b;
}
// String manipulation
char* greet(const char* name) {
char* result = malloc(256);
snprintf(result, 256, "Hello from C, %s!", name);
return result;
}
// Struct definition
typedef struct {
double x;
double y;
} Point;
double distance(Point a, Point b) {
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx*dx + dy*dy);
}
*/
import "C" // Must be immediately after preamble, no blank line
import (
"fmt"
"unsafe"
)
func main() {
// Call C function
result := C.add(C.int(3), C.int(4))
fmt.Printf("C.add(3, 4) = %d\n", int(result))
// String: Go → C → Go (with memory management)
goName := "Alice"
cName := C.CString(goName) // Allocates C string (must free!)
defer C.free(unsafe.Pointer(cName))
cGreeting := C.greet(cName) // Returns C string (must free!)
defer C.free(unsafe.Pointer(cGreeting))
goGreeting := C.GoString(cGreeting)
fmt.Printf("C.greet() = %q\n", goGreeting)
// Struct passing
a := C.Point{x: C.double(0), y: C.double(0)}
b := C.Point{x: C.double(3), y: C.double(4)}
dist := C.distance(a, b)
fmt.Printf("C.distance((0,0), (3,4)) = %.2f\n", float64(dist))
}Step 2: Export Go Functions to C
Step 3: Memory Management Rules
Step 4: CGO Performance Overhead
Step 5: CGO with Real Libraries
Step 6: Runtime.Pinner — Safe Pointer Pinning (Go 1.21+)
Step 7: CGO Build Configuration
Step 8: Capstone — CGO Demonstration
Summary
Operation
API
Memory Owner
Last updated
