【问题标题】:cgo: Converting `[]uchar` to `[]byte`cgo:将 `[]uchar` 转换为 `[]byte`
【发布时间】:2020-03-24 00:15:18
【问题描述】:

首先,cgo 很酷,谢谢 :)

不过我确实有一个问题,我有很多只包含一个字节数组的 C 结构,我想将其中的数组用作 []byte。即:

typedef struct {
    unsigned char data[64];
} pubkey;

我希望能够做到:

type SchnorrPublicKey struct {
    pubkey C.pubkey
}

func (key *SchnorrPublicKey) String() string {
    return hex.EncodeToString(key.pubkey.data[:])
}

但我收到以下错误: ./schnorr.go:39:43: cannot use key.pubkey.data[:] (type []_Ctype_uchar) as type []byte in argument to hex.EncodeToString 我可以通过执行以下操作来完成此工作: return hex.EncodeToString(C.GoBytes(unsafe.Pointer(&key.pubkey.data[0]), C.int(len(key.pubkey.data))))

但感觉有点愚蠢,将一个已经 go slice 转换为另一个 go slice 只是为了将 _Ctype_uchar 类型替换为 byte 类型非常复杂,而且它们是 100% 兼容的。

有没有更好的方法来做到这一点?

【问题讨论】:

  • 为什么你首先有一个[]C.uchar_Ctype_uchar 在 Go 中用处不大,切片在 C 中用处不大。似乎一开始不创建这样的混合类型会更容易。
  • 这是cgo在go中自动生成一个C结构的结果。 unsigned char data[64]; 数组在 go 中表示为 []_Ctype_uchar
  • 我怀疑它是在创建一个[]_Ctype_uchar,否则你不需要[:] 切片符号。 GoBytes 是用于将数据复制到 Go 内存中的正确函数,或者:stackoverflow.com/questions/28925179/…,
  • 这里也有介绍:github.com/golang/go/wiki/cgo

标签: go cgo


【解决方案1】:

https://golang.org/issue/19367 中有一个公开提议的函数来执行此操作。

与此同时,如果切片大小的上限是恒定的(在本例中为64):

    var cPtr = &key.pubkey.data[0]
    const upperBound = 64
    var n = 64

    slice := (*[upperBound]byte)(unsafe.Pointer(cPtr))[:n:n]

如果您不这样做,请参阅https://github.com/golang/go/issues/13656#issuecomment-303216308 中的函数。

【讨论】:

    猜你喜欢
    • 2012-01-26
    • 2011-06-08
    • 1970-01-01
    • 2014-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    相关资源
    最近更新 更多