The cgo code below has a function to put a Go value in a C buffer, and two alternative functions to get it back; getViaGoBytes and getDirect.
Is getViaGoBytes any better than getDirect?
I assume not, and the intermediary slice created in getViaGoBytes is unnecessary.
Am I correct in thinking Go allocates enough memory when the uint64 y variable is declared, and the assignment to y copies the memory from C to Go?
package main
/*
char buf[8];
void put(char * input, int size) {
while (size--) {
buf[size] = input[size];
}
}
*/
import "C"
import "unsafe"
func put(input uint64) {
C.put((*C.char)(unsafe.Pointer(&input)), C.int(unsafe.Sizeof(input)))
}
func getViaGoBytes() uint64 {
var out uint64
data := C.GoBytes(unsafe.Pointer(&(C.buf[0])), C.int(unsafe.Sizeof(out)))
out = *(*uint64)(unsafe.Pointer(&data[0]))
return out
}
func getDirect() uint64 {
return *(*uint64)(unsafe.Pointer(&(C.buf[0])))
}
func main() {
var input uint64 = 1<<64 - 1
println(input)
put(input)
var x uint64 = getViaGoBytes()
println(x)
var y uint64 = getDirect()
println(y)
}
Marking question answered by copying JimB's answer from comment:
GoBytes copies a C allocated buffer into a slice with Go allocated memory. If that's what you want, then use GoBytes. Here you're not even keeping that copy, so there's no reason to do it.
Also, benchmark is interesting:
$ go test -bench . -benchmem
BenchmarkGoBytes-8 20000000 97.8 ns/op 32 B/op 3 allocs/op
BenchmarkDirect-8 2000000000 0.84 ns/op 0 B/op 0 allocs/op
PASS