aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorJames Bardin <j.bardin@gmail.com>2016-03-16 13:53:53 -0400
committerIan Lance Taylor <iant@golang.org>2016-03-16 23:22:10 +0000
commit5a34472d74637c84752d2c13ace78e4e6ab756b7 (patch)
tree293131d3c10cfec05a33d75b4ef2a767a4f5a885 /src/cmd
parent3e54ca9a4624fda0bcd76192aa529e826ef12b4f (diff)
downloadgo-5a34472d74637c84752d2c13ace78e4e6ab756b7.tar.xz
cmd/cgo: add C.CBytes
Add a C.CBytes function to copy a Go byte slice into C memory. This returns an unsafe.Pointer, since that is what needs to be passed to C.free, and the data is often opaque bytes anyway. Fixes #14838 Change-Id: Ic7bc29637eb6f1f5ee409b3898c702a59833a85a Reviewed-on: https://go-review.googlesource.com/20762 Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/cgo/doc.go7
-rw-r--r--src/cmd/cgo/out.go18
2 files changed, 25 insertions, 0 deletions
diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go
index 61e480c585..6e0bfa58c6 100644
--- a/src/cmd/cgo/doc.go
+++ b/src/cmd/cgo/doc.go
@@ -198,6 +198,13 @@ by making copies of the data. In pseudo-Go definitions:
// 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
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
index 40c76b52e4..621c41c6b2 100644
--- a/src/cmd/cgo/out.go
+++ b/src/cmd/cgo/out.go
@@ -533,6 +533,7 @@ func fixGo(name string) string {
var isBuiltin = map[string]bool{
"_Cfunc_CString": true,
+ "_Cfunc_CBytes": true,
"_Cfunc_GoString": true,
"_Cfunc_GoStringN": true,
"_Cfunc_GoBytes": true,
@@ -1324,6 +1325,7 @@ _GoString_ GoString(char *p);
_GoString_ GoStringN(char *p, int l);
_GoBytes_ GoBytes(void *p, int n);
char *CString(_GoString_);
+void *CBytes(_GoBytes_);
void *_CMalloc(size_t);
`
@@ -1389,6 +1391,15 @@ func _Cfunc_CString(s string) *_Ctype_char {
}
`
+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))
@@ -1400,6 +1411,7 @@ var builtinDefs = map[string]string{
"GoStringN": goStringNDef,
"GoBytes": goBytesDef,
"CString": cStringDef,
+ "CBytes": cBytesDef,
"_CMalloc": cMallocDef,
}
@@ -1437,6 +1449,12 @@ const char *_cgoPREFIX_Cfunc_CString(struct __go_string s) {
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);