CGo 将 go 字符串转换为 *C.uchar

标签 c go cgo

var originalMsg *C.uchar
C.ecall_pay_w(8, 10, &originalMsg, &signature)
originalMsgStr := fmt.Sprintf("%c", originalMsg)

//Todo convert originalMstStr to same value with originalMsg

我必须将 go str(originalMsgStr) 转换为 *C.uchar 类型,该类型与originalMsg 的值相同。 我该怎么做?

最佳答案

您从对 C.ecall_pay_w 的调用中返回一个 C 字符串,并希望将该 C 字符串转换为 Go 字符串。您可以通过手动跟踪 C 字符串直到到达终止 0 来完成此操作。

假设:

  • C 字符串末尾有一个终止符 0
  • C 字符串被编码为 ASCII,因此每个字节代表一个 ASCII 字符(范围为 [0..127])。这意味着它同时是 ASCII 和 UTF-8,因为 UTF-8 向后兼容 ASCII。

那么你的解决方案可能是这样的:

    func convertCStringToGoString(c *C.uchar) string {
        var buf []byte
        for *c != 0 {
            buf = append(buf, *c)
            c = (*C.uchar)(unsafe.Pointer(uintptr(unsafe.Pointer(c)) + 1))
        }
        return string(buf)
    }

请注意,在 Go 中做这样的“不安全”事情是需要大量强制转换的。这是 Go 作者故意这样做的。您需要先转换为 unsafe.Pointer,然后才能转换为 uintptruintptr 可以添加到 (+ 1),而 unsafe.Pointer 不支持这一点。这些就是进行如此多选角的原因。

关于CGo 将 go 字符串转换为 *C.uchar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59827026/

相关文章:

c - 如何在C中将字符串格式化为排队格式?

go - 如何在 Go 中包含来自第三方包的 header ?

c - 将全零分配给 C 中的嵌套结构(GCC 版本 < 5)

c - 使用 scanf 将变量放入带有 C 的数组中

c - 用 C 读取文件不起作用?

go - Go 中的相同算法、多种输入和输出类型的可能性?

go - golang 中的 select{} 和 for{} 有什么区别?

go - 从 Redis/Golang 客户端读取整个数据

go - CGO 指针检查中的已知实现错误

go - #cgo LDFLAGS中的无效标志