-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhello_module.go
More file actions
103 lines (88 loc) · 3.18 KB
/
hello_module.go
File metadata and controls
103 lines (88 loc) · 3.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package main
// #include <stdlib.h>
// #include "redismodule.h"
import "C"
import (
"github.com/amyangfei/RedisModules-Go/cgoutils"
"math/rand"
"time"
"unsafe"
)
//export GoEcho1
// c->go: Convert C string to Go string
// go->c: Create C string via C.CString, return pointer and length of string
func GoEcho1(s *C.char) (*C.char, int) {
gostr := (C.GoString(s) + " from golang1")
return C.CString(gostr), len(gostr)
}
//export GoEcho2
// c->go: Convert C array with explicit length to Go []byte using C.GoBytes
// go->c: Create C string via C.CString, return pointer and length of string
func GoEcho2(s *C.char, length C.int) (*C.char, int) {
slice := C.GoBytes(unsafe.Pointer(s), length)
slice = append(slice, " from golang2"...)
return C.CString(string(slice)), len(slice)
}
//export GoEcho3
// c->go: Convert C array with explicit length to Go []byte using C.GoBytes
// go->c: malloc the C buffer, and make a single copy into that buffer. It is
// important to keep in mind that the Go garbage collector will not interact
// with this data, and that if it is freed from the C side of things
func GoEcho3(s *C.char, length C.int) (unsafe.Pointer, int) {
slice := C.GoBytes(unsafe.Pointer(s), length)
slice = append(slice, " from golang3"...)
p := C.malloc(C.size_t(len(slice)))
// free memory in c code
// defer C.free(p)
cBuf := (*[1 << 30]byte)(p)
copy(cBuf[:], slice)
return p, len(slice)
}
//export GoEcho4
// c->go: using reflect to bind C memory to Go resource without memory copy.
// Fullfill c memory directly
func GoEcho4(s *C.char, length C.int) (unsafe.Pointer, int) {
incr := " from golang4"
cap := int(length) + len(incr)
zslice := cgoutils.ZeroCopySlice(unsafe.Pointer(s), int(length), cap, false)
copy(zslice.Data[int(length):cap], incr)
return unsafe.Pointer(&zslice.Data[0]), cap
}
//export GoEcho5
// error handler example
func GoEcho5(s *C.char) (*C.char, int, *C.char, int) {
source := rand.NewSource(time.Now().UnixNano())
r := rand.New(source)
if r.Intn(2) == 1 {
err := "random system error"
return C.CString(""), 0, C.CString(err), len(err)
} else {
gostr := (C.GoString(s) + " from golang5")
return C.CString(gostr), len(gostr), C.CString(""), 0
}
}
//export GoEcho6
// c->go: using reflect to bind C memory to Go resource without memory copy.
// Fullfill c memory directly
func GoEcho6(s *C.char, length, capacity C.int) (unsafe.Pointer, int) {
incr := " from golang6"
zslice := cgoutils.ZeroCopySlice(unsafe.Pointer(s), int(capacity), int(capacity), false)
copy(zslice.Data[int(length):], incr)
return unsafe.Pointer(&zslice.Data[0]), int(length) + len(incr)
}
//export GoEcho7
// c->go: using reflect to bind C memory to Go resource without memory copy.
// go->c: malloc the C buffer, and make a single copy into that buffer.
func GoEcho7(s *C.char, length C.int) (unsafe.Pointer, int) {
incr := " from golang7"
// cap := int(length) + len(incr)
zslice := cgoutils.ZeroCopySlice(unsafe.Pointer(s), int(length), int(length), false)
zslice.Data = append(zslice.Data, incr...)
p := C.malloc(C.size_t(len(zslice.Data)))
// free memory in c code
// defer C.free(p)
cBuf := (*[1 << 30]byte)(p)
copy(cBuf[:], zslice.Data)
return p, len(zslice.Data)
}
func main() {}