func slice() { fmt.Printf("Slice:\n") var a [10]byte // reflect.SliceHeader is a runtime representation of the internal workings // of a slice. To make it point to a specific address, use something like // the following: // h.Data = uintptr(0x100) // And replace '0x100' with the desired address. var h reflect.SliceHeader h.Data = uintptr(unsafe.Pointer(&a)) // The address of the first element of the underlying array. h.Len = len(a) h.Cap = len(a) // Create an actual slice from the SliceHeader. s := *(*[]byte)(unsafe.Pointer(&h)) fmt.Printf("Before:\n\ts: %v\n\ta: %v\n", s, a) // Copy a string into the slice. This fills the underlying array, which in // this case has been manually set to 'a'. copy(s, "A string.") fmt.Printf("After:\n\ts: %v\n\ta: %v\n", s, a) }
func (repo *Repository) TagListMatch(pattern string) ([]string, error) { cpattern := C.CString(pattern) defer C.free(unsafe.Pointer(cpattern)) var ctags C.git_strarray defer C.git_strarray_free(&ctags) ecode := C.git_tag_list_match(&ctags, cpattern, repo.git_repository) if ecode != git_SUCCESS { return nil, gitError() } // TODO: Find a safer way if one exists. var tagsSlice reflect.SliceHeader length := int(ctags.count) tagsSlice.Data = uintptr(unsafe.Pointer(ctags.strings)) tagsSlice.Len = length tagsSlice.Cap = length ctagStrings := *(*[]*C.char)(unsafe.Pointer(&tagsSlice)) tags := make([]string, length) for i := 0; i < len(ctagStrings); i++ { tags[i] = C.GoString(ctagStrings[i]) } return tags, nil }
func (repo *Repository) ListBranches(flags ...BranchType) ([]string, error) { var cnames C.git_strarray defer C.git_strarray_free(&cnames) var cflags C.uint if len(flags) == 0 { cflags = C.uint(BRANCH_ALL) } else { for _, flag := range flags { cflags |= C.uint(flag) } } ecode := C.git_branch_list(&cnames, repo.git_repository, cflags) if ecode != git_SUCCESS { return nil, gitError() } // TODO: Find a safer way if one exists. var namesSlice reflect.SliceHeader length := int(cnames.count) namesSlice.Data = uintptr(unsafe.Pointer(cnames.strings)) namesSlice.Len = length namesSlice.Cap = length cnameStrings := *(*[]*C.char)(unsafe.Pointer(&namesSlice)) names := make([]string, length) for i := 0; i < len(cnameStrings); i++ { names[i] = C.GoString(cnameStrings[i]) } return names, nil }
func GetKeyboardState() []uint8 { var numkeys C.int start := C.SDL_GetKeyboardState(&numkeys) sh := reflect.SliceHeader{} sh.Len = int(numkeys) sh.Cap = int(numkeys) sh.Data = uintptr(unsafe.Pointer(start)) return *(*[]uint8)(unsafe.Pointer(&sh)) }
func utf16slice(ptr *uint16) []uint16 { hdr := reflect.SliceHeader{Data: uintptr(unsafe.Pointer(ptr)), Len: 1, Cap: 1} slice := *((*[]uint16)(unsafe.Pointer(&hdr))) i := 0 for slice[len(slice)-1] != 0 { i++ } hdr.Len = i slice = *((*[]uint16)(unsafe.Pointer(&hdr))) return slice }
func init() { data := new(reflect.SliceHeader) data.Cap = 10 data.Len = 10 data.Data = uintptr(C.calloc(1, C.size_t(unsafe.Sizeof(SomeStruct{})))) someData = *(*[]SomeStruct)(unsafe.Pointer(data)) for i := 0; i < len(someData); i++ { someData[i] = SomeStruct{ Id: i, Name: "你好" + strconv.Itoa(i), } } }
func LoadWAV(file string) (*AudioSpec, []byte, error) { cfile := C.CString(file) defer C.free(unsafe.Pointer(cfile)) var a AudioSpec var h reflect.SliceHeader var l C.Uint32 if C.LoadWAV(cfile, a.c(), (**C.Uint8)(unsafe.Pointer(&h.Data)), &l) == nil { return nil, nil, getError() } h.Len = int(l) h.Cap = int(l) return &a, *(*[]byte)(unsafe.Pointer(&h)), nil }
func LoadWAV_RW(rw *RWops, free bool) (*AudioSpec, []byte, error) { var cfree C.int if free { cfree = 1 } var a AudioSpec var h reflect.SliceHeader var l C.Uint32 if C.SDL_LoadWAV_RW(rw.c, cfree, a.c(), (**C.Uint8)(unsafe.Pointer(&h.Data)), &l) == nil { return nil, nil, getError() } h.Len = int(l) h.Cap = int(l) return &a, *(*[]byte)(unsafe.Pointer(&h)), nil }
func (repo *Repository) ListReferences(flags RefType) ([]string, error) { var crefs C.git_strarray defer C.git_strarray_free(&crefs) ecode := C.git_reference_list(&crefs, repo.git_repository, C.uint(flags)) if ecode != git_SUCCESS { return nil, gitError() } // TODO: Find a safer way if one exists. var refsSlice reflect.SliceHeader length := int(crefs.count) refsSlice.Data = uintptr(unsafe.Pointer(crefs.strings)) refsSlice.Len = length refsSlice.Cap = length crefStrings := *(*[]*C.char)(unsafe.Pointer(&refsSlice)) refs := make([]string, length) for i := 0; i < len(crefStrings); i++ { refs[i] = C.GoString(crefStrings[i]) } return refs, nil }
func (repo *Repository) GetManyAttrs(path string, names []string, flags ...AttrFlag) ([]string, error) { var values [1]int8 cvalues := (*C.char)(&values[0]) cpath := C.CString(path) defer C.free(unsafe.Pointer(cpath)) length := len(names) clength := C.size_t(length) cnames := make([]*C.char, length) for i := 0; i < length; i++ { cnames[i] = C.CString(names[i]) defer C.free(unsafe.Pointer(cnames[i])) } var cflags C.uint32_t for _, flag := range flags { cflags |= C.uint32_t(flag) } ecode := C.git_attr_get_many(&cvalues, repo.git_repository, cflags, cpath, clength, &cnames[0]) if ecode != git_SUCCESS { return nil, gitError() } // TODO: Find a safer way if one exists. var valuesSlice reflect.SliceHeader valuesSlice.Data = uintptr(unsafe.Pointer(cvalues)) valuesSlice.Len = length valuesSlice.Cap = length cvalueStrings := *(*[]*C.char)(unsafe.Pointer(&valuesSlice)) valuesOut := make([]string, length) for i := 0; i < length; i++ { valuesOut[i] = C.GoString(cvalueStrings[i]) } return valuesOut, nil }
func main() { data1 := initTestData() checkTestData(len(data1), data1) itemSize := unsafe.Sizeof(BigStruct{}) csize := C.size_t(itemSize * uintptr(len(data1))) t1 := time.Now().Nanosecond() mem := C.malloc(csize) C.memcpy(mem, unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&data1)).Data), csize) t2 := time.Now().Nanosecond() println("Go to C:", (t2-t1)/int(time.Microsecond)) data2 := new(reflect.SliceHeader) data2.Cap = len(data1) data2.Len = len(data1) data2.Data = uintptr(mem) checkTestData(len(data1), *(*[]BigStruct)(unsafe.Pointer(data2))) t3 := time.Now().Nanosecond() data3 := make([]BigStruct, len(data1)) copy(data3, *(*[]BigStruct)(unsafe.Pointer(data2))) t4 := time.Now().Nanosecond() checkTestData(len(data1), data3) println("C to Go:", (t4-t3)/int(time.Microsecond)) }
func main() { var a []byte var e []byte var r reflect.SliceHeader fmt.Println("A", A) a = A[2:10] fmt.Println("a.cap", cap(a)) fmt.Println("a", a) d := (unsafe.Pointer(&A)) fmt.Println("d", d) r.Data = uintptr(unsafe.Pointer(&A)) r.Len = 4 r.Cap = 10 e = *(*[]byte)(unsafe.Pointer(&r)) //e = a fmt.Println("e", e) var rec Rec f := unsafe.Sizeof(rec) fmt.Println("sizeof rec", f) /* fmt.Println("A", A) a := A[2:10] fmt.Println("a", a) b := unsafe.Pointer(&A) fmt.Println("b", b) c := unsafe.Pointer(&a) fmt.Println("c", c) d := (*[2]Rec)(unsafe.Pointer(&a[2])) fmt.Println("d", d) head := (* Head)(unsafe.Pointer(&A)) fmt.Println("head", head) fmt.Println("*head", *head) fmt.Println(unsafe.Sizeof(I)) fmt.Println(unsafe.Sizeof(leafhead)) fmt.Println(sizeHead) */ }
func NewFromFile(filename string) (*Continuum, error) { var cont C.ketama_continuum fn := C.CString(filename) defer C.free(unsafe.Pointer(fn)) rv := C.ketama_roll(&cont, fn) if rv == 0 { errMsg := C.GoString(C.ketama_error()) return nil, errors.New(errMsg) } addrMap := make(map[string]net.Addr) var mcsSlice reflect.SliceHeader mcsSlice.Data = uintptr(cont.array) mcsSlice.Len = int(cont.numpoints) mcsSlice.Cap = int(cont.numpoints) mcss := *(*[]C.mcs)(unsafe.Pointer(&mcsSlice)) for _, mcs := range mcss { ip := C.GoString(C.get_ip(&mcs)) addrMap[ip], _ = getServerAddr(ip) } return &Continuum{&cont, addrMap}, nil }
func setSlice(s *reflect.SliceHeader, data uintptr, n int) { s.Data = data s.Len = n s.Cap = n }
func setupSlice(hdr *reflect.SliceHeader, ptr unsafe.Pointer, size C.size_t) { hdr.Cap = int(size) hdr.Len = int(size) hdr.Data = uintptr(ptr) }
func newRawSliceHeader(sh *reflect.SliceHeader, b []byte, stride int) *reflect.SliceHeader { sh.Len = len(b) / stride sh.Cap = len(b) / stride sh.Data = (uintptr)(unsafe.Pointer(&b[0])) return sh }