package main

// #include <stdio.h>
// #include <stdlib.h>
//
// void print(char *str) {
//     printf("%s\\n", str);
// }
import "C"

import "unsafe"

func main() {
    s := "Hello, Cgo"
    cs := C.CString(s)
    defer C.free(unsafe.Pointer(cs))
    C.print(cs) // Hello, Cgo
}
C.char,
C.schar (signed char),
C.uchar (unsigned char),
C.short,
C.ushort (unsigned short),
C.int, C.uint (unsigned int),
C.long,
C.ulong (unsigned long),
C.longlong (long long),
C.ulonglong (unsigned long long),
C.float,
C.double
package main

// int cArray[] = {1, 2, 3, 4, 5, 6, 7};
import "C"
import (
    "fmt"
    "unsafe"
)

func CArrayToGoArray(cArray unsafe.Pointer, elemSize uintptr, len int) (goArray []int32) {
    for i := 0; i < len; i++ {
        j := *(*int32)((unsafe.Pointer)(uintptr(cArray) + uintptr(i)*elemSize))
        goArray = append(goArray, j)
    }
    return
}

func main() {
    goArray := CArrayToGoArray(unsafe.Pointer(&C.cArray[0]),
        unsafe.Sizeof(C.cArray[0]), 7)
    fmt.Println(goArray) // [1 2 3 4 5 6 7]
}
package main

// enum color {
//     RED,
//     BLUE,
//     YELLOW
// };
import "C"
import "fmt"

func main() {
    var e, f, g C.enum_color = C.RED, C.BLUE, C.YELLOW
    fmt.Println(e, f, g) // 0 1 2
}
package main

// #include <stdlib.h>
//
// struct employee {
//     char *id;
//     int  age;
// };
import "C"

import (
    "fmt"
    "unsafe"
)

func main() {
    id := C.CString("1247")
    defer C.free(unsafe.Pointer(id))

    var p = C.struct_employee{
        id:  id,
        age: 21,
    }
    fmt.Printf("%#v\\n", p) // main._Ctype_struct_employee{id:(*main._Ctype_char)(0x9800020), age:21, _:[4]uint8{0x0, 0x0, 0x0, 0x0}}
}
package main

// #include <stdio.h>
// union bar {
//     char   c;
//     int    i;
//     double d;
// };
import "C"
import "fmt"

func main() {
    var b *C.union_bar = new(C.union_bar)
    b[0] = 4
    fmt.Println(b) // &[4 0 0 0 0 0 0 0]
}
// typedef int myint;
var a C.myint = 5
fmt.Println(a)

// typedef struct employee myemployee;
var m C.struct_myemployee
package main

// struct employee {
//     char *id;
//     int  age;
// };
import "C"

import (
    "fmt"
)

func main() {
    fmt.Printf("%#v\\n", C.sizeof_int)             // 4
    fmt.Printf("%#v\\n", C.sizeof_char)            // 1
    fmt.Printf("%#v\\n", C.sizeof_struct_employee) // 16
}
// foo.go
package main

// #cgo CFLAGS: -I${SRCDIR}
// #cgo LDFLAGS: -L${SRCDIR} -lfoo
// #include <stdio.h>
// #include <stdlib.h>
// #include "foo.h"
import "C"
import "fmt"

func main() {
    fmt.Println(C.count)
    C.foo()
}

// foo.h

extern int count;
void foo();

// foo.c

#include "foo.h"

int count = 6;
void foo() {
    printf("I am foo!\\n");
}

$gcc -c foo.c
$ar rv libfoo.a foo.o
$go build foo.go
$./foo

$gcc -c foo.c
$gcc -shared -Wl,-soname,libfoo.so -o libfoo.so  foo.o (在linux上)
package main

// #include <stdlib.h>
// #include <stdio.h>
// #include <errno.h>
// int foo(int i) {
//     errno = 0;
//     if (i > 5) {
//         errno = 8;
//         return i - 5;
//     } else {
//         return i;
//     }
//}
import "C"
import "fmt"

func main() {
    i, err := C.foo(C.int(8))
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(i)
    }
}