func Test12030(t *testing.T) { test12030(t) }
func TestGCC68255(t *testing.T) { testGCC68255(t) }
func TestCallGoWithString(t *testing.T) { testCallGoWithString(t) }
+func Test14838(t *testing.T) { test14838(t) }
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
--- /dev/null
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 14838. add CBytes function
+
+package cgotest
+
+/*
+#include <stdlib.h>
+
+int check_cbytes(char *b, size_t l) {
+ int i;
+ for (i = 0; i < l; i++) {
+ if (b[i] != i) {
+ return 0;
+ }
+ }
+ return 1;
+}
+*/
+import "C"
+
+import (
+ "testing"
+ "unsafe"
+)
+
+func test14838(t *testing.T) {
+ data := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
+ cData := C.CBytes(data)
+ defer C.free(cData)
+
+ if C.check_cbytes((*C.char)(cData), C.size_t(len(data))) == 0 {
+ t.Fatalf("mismatched data: expected %v, got %v", data, (*(*[10]byte)(unsafe.Pointer(cData)))[:])
+ }
+}
// if C.free is needed).
func C.CString(string) *C.char
+ // Go []byte slice to C array
+ // The C array is allocated in the C heap using malloc.
+ // It is the caller's responsibility to arrange for it to be
+ // freed, such as by calling C.free (be sure to include stdlib.h
+ // if C.free is needed).
+ func C.CBytes([]byte) unsafe.Pointer
+
// C string to Go string
func C.GoString(*C.char) string
var isBuiltin = map[string]bool{
"_Cfunc_CString": true,
+ "_Cfunc_CBytes": true,
"_Cfunc_GoString": true,
"_Cfunc_GoStringN": true,
"_Cfunc_GoBytes": true,
_GoString_ GoStringN(char *p, int l);
_GoBytes_ GoBytes(void *p, int n);
char *CString(_GoString_);
+void *CBytes(_GoBytes_);
void *_CMalloc(size_t);
`
}
`
+const cBytesDef = `
+func _Cfunc_CBytes(b []byte) unsafe.Pointer {
+ p := _cgo_runtime_cmalloc(uintptr(len(b)))
+ pp := (*[1<<30]byte)(p)
+ copy(pp[:], b)
+ return p
+}
+`
+
const cMallocDef = `
func _Cfunc__CMalloc(n _Ctype_size_t) unsafe.Pointer {
return _cgo_runtime_cmalloc(uintptr(n))
"GoStringN": goStringNDef,
"GoBytes": goBytesDef,
"CString": cStringDef,
+ "CBytes": cBytesDef,
"_CMalloc": cMallocDef,
}
return p;
}
+void *_cgoPREFIX_Cfunc_CBytes(struct __go_open_array b) {
+ char *p = malloc(b.__count);
+ memmove(p, b.__data, b.__count);
+ return p;
+}
+
struct __go_string _cgoPREFIX_Cfunc_GoString(char *p) {
intgo len = (p != NULL) ? strlen(p) : 0;
return __go_byte_array_to_string(p, len);