如何将 [1024]C.char 转换为 [1024]byte?

6

请问如何将以下 C (数组) 类型进行转换:

char my_buf[BUF_SIZE];

转换为Go语言的数组类型:

type buffer [C.BUF_SIZE]byte

尝试进行接口转换时,出现以下错误:
cannot convert (*_Cvar_my_buf) (type [1024]C.char) to type [1024]byte
2个回答

10
最简单和最安全的方法是将其复制到一个切片中,而不是专门使用 [1024]byte
mySlice := C.GoBytes(unsafe.Pointer(&C.my_buff), C.BUFF_SIZE)

为了直接使用内存而不进行复制,您可以通过unsafe.Pointer进行“类型转换”。
mySlice := (*[1 << 30]byte)(unsafe.Pointer(&C.my_buf))[:int(C.BUFF_SIZE):int(C.BUFF_SIZE)]
// or for an array if BUFF_SIZE is a constant
myArray := *(*[C.BUFF_SIZE]byte)(unsafe.Pointer(&C.my_buf))

我需要的是一个数组,而不是切片。原因之一是我确实想要复制。另外,C.BUF_SIZE 一个常数,所以我可以在 typedef 中使用它。另外,为什么要将其转换为指向一个巨大数组的指针? - Attila O.
2
这个巨大的数组只是为了让Go编译器接受任何有效的大小,但它实际上并没有被分配(在这里可以看到一些其他的例子https://github.com/golang/go/wiki/cgo)。 - JimB

2
为了创建一个包含C.my_buf内容的Go slice:
arr := C.GoBytes(unsafe.Pointer(&C.my_buf), C.BUF_SIZE)

To create a Go array...

var arr [C.BUF_SIZE]byte
copy(arr[:], C.GoBytes(unsafe.Pointer(&C.my_buf), C.BUF_SIZE))

1
@JimB 第二个例子对我来说似乎可以工作。这里有一个例子 https://play.golang.org/p/O49FFSyHCG (本地测试)。你得到了什么错误?我在 Mac 上运行 go1.4。 - tidwall
啊,我从来没有检查过cgo是否将DEFINE视为常量。在这种情况下确实有效。 - JimB
1
FYI,第二个示例会复制数据两次。 - JimB
@JimB 哦。我原本以为 C.GoBytes 会返回一个指向底层 C 数组的 []byte。现在我明白它确实会复制一份。 - Attila O.
@AttilaO。没有任何区别。 - tidwall
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接