|
| 1 | +package main |
| 2 | + |
| 3 | +/* |
| 4 | +#cgo CFLAGS: -I${SRCDIR}/ctestlib |
| 5 | +#cgo LDFLAGS: -Wl,-rpath,${SRCDIR}/ctestlib |
| 6 | +#cgo LDFLAGS: -L${SRCDIR}/ctestlib |
| 7 | +#cgo LDFLAGS: -ltest |
| 8 | +
|
| 9 | +#include <test.h> |
| 10 | +*/ |
| 11 | +import "C" |
| 12 | +import ( |
| 13 | + "bytes" |
| 14 | + "fmt" |
| 15 | + "unsafe" |
| 16 | +) |
| 17 | + |
| 18 | +type User struct { |
| 19 | + Username string |
| 20 | + Visits int |
| 21 | +} |
| 22 | + |
| 23 | +type Status int |
| 24 | + |
| 25 | +const ( |
| 26 | + Pending Status = iota |
| 27 | + Done |
| 28 | +) |
| 29 | + |
| 30 | +func evenNumberCallback(num int) { |
| 31 | + fmt.Println("odd number: ", num) |
| 32 | +} |
| 33 | + |
| 34 | +func userCallback(user unsafe.Pointer) { |
| 35 | + u := (*User)(unsafe.Pointer(user)) |
| 36 | + u.Visits++ |
| 37 | +} |
| 38 | + |
| 39 | +func main() { |
| 40 | + // Numbers |
| 41 | + fmt.Println("\nNumbers") |
| 42 | + |
| 43 | + a := 1 |
| 44 | + b := 2 |
| 45 | + sum := int(C.sum(C.int(a), C.int(b))) |
| 46 | + fmt.Print(sum, "\n\n") |
| 47 | + |
| 48 | + // Get string |
| 49 | + fmt.Println("Get string") |
| 50 | + getString := C.GoString(C.get_string()) |
| 51 | + fmt.Println(getString) |
| 52 | + stringBytes := C.GoBytes(unsafe.Pointer(C.get_string()), 24) |
| 53 | + fmt.Println(stringBytes[0:bytes.Index(stringBytes, []byte{0})]) |
| 54 | + fmt.Println() |
| 55 | + |
| 56 | + // Send string |
| 57 | + fmt.Println("Send string") |
| 58 | + str := "lorem ipsum" |
| 59 | + cStr := C.CString(str) |
| 60 | + C.print_string(cStr) |
| 61 | + C.free(unsafe.Pointer(cStr)) |
| 62 | + fmt.Println() |
| 63 | + |
| 64 | + // Send bytes |
| 65 | + fmt.Println("Send byte array") |
| 66 | + data := []byte{1, 4, 2} |
| 67 | + cBytes := (*C.uchar)(unsafe.Pointer(&data[0])) |
| 68 | + cBytesLength := C.size_t(len(data)) |
| 69 | + fmt.Print("bytes: ") |
| 70 | + C.print_buffer(cBytes, cBytesLength) |
| 71 | + fmt.Println() |
| 72 | + |
| 73 | + // Struct |
| 74 | + fmt.Println("Get and pass struct") |
| 75 | + point := C.struct_point{} |
| 76 | + point.x = 0 |
| 77 | + point.y = 2 |
| 78 | + fmt.Println(point) |
| 79 | + fmt.Print(C.point_diff(point), "\n\n") |
| 80 | + |
| 81 | + // Arbitrary data: unsafe.Pointer to void pointer |
| 82 | + fmt.Println("Pass void pointer") |
| 83 | + C.pass_void_pointer(unsafe.Pointer(&point.y)) |
| 84 | + fmt.Println() |
| 85 | + |
| 86 | + // Enum |
| 87 | + fmt.Println("Access enum") |
| 88 | + fmt.Print(C.enum_status(Pending) == C.PENDING, C.PENDING, C.DONE, "\n\n") |
| 89 | + |
| 90 | + // Callback |
| 91 | + fmt.Println("Pass callback") |
| 92 | + c := registerCallback(evenNumberCallback, nil) |
| 93 | + C.generate_numbers(5, c) |
| 94 | + unregisterCallback(c) |
| 95 | + |
| 96 | + // Callback with params |
| 97 | + user := User{ |
| 98 | + Username: "johndoe", |
| 99 | + } |
| 100 | + cWithParams := registerCallback(userCallback, unsafe.Pointer(&user)) |
| 101 | + C.user_action(cWithParams) |
| 102 | + unregisterCallback(cWithParams) |
| 103 | + fmt.Println(user) |
| 104 | +} |
0 commit comments