C.GoBytes需要检索C缓冲区,还是指针足够?

时间:2016-11-20 20:19:09

标签: c go cgo

下面的cgo代码具有将Go值放入C缓冲区的功能,以及两个替代函数来取回它; getViaGoBytes和getDirect。

getViaGoBytes比getDirect更好吗?

我假设没有,并且在getViaGoBytes中创建的中间片是不必要的。

我是否正确认为Go在声明uint64 y变量时分配足够的内存,而y的赋值将内存从C复制到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)
}

1 个答案:

答案 0 :(得分:1)

通过复制JimB的答案来回答标记问题:

  

GoBytes将C分配的缓冲区复制到分配了Go的切片中   记忆。如果这是你想要的,那就使用GoBytes。在这里,你不是   即使保留该副本,也没有理由这样做。

此外,基准测试很有意思:

$ 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