访问字符串的原始字节

Access the raw bytes of a string

我正在尝试调用一个 C 函数,该函数需要来自 go 的 C 字符串 (char*)。我知道 cgo documentation 中记录的 C.CString 函数,但由于我调用的函数已经制作了一个副本,所以我试图避免 Cstring 制作的那个。

现在,我正在做这个,s作为一个 go string

 var cs *C.char = (*C.char)( unsafe.Pointer(& []byte(s) [0]))

但我感觉 []bytes(s) 正在制作自己的副本。有可能只得到 char* 吗?

如果您这样做的次数足够多以至于性能成为一个问题,那么一开始就将数据保存在一个切片中确实是明智的。

如果真的想访问字符串的地址,可以使用unsafe包将其转换为匹配字符串头的struct。使用 reflect.StringHeader 类型:

p := unsafe.Pointer((*(*reflect.StringHeader)(unsafe.Pointer(&s))).Data)

或者使用切片作为代理,因为它们都将数据指针和长度整数放在相同的字段位置

p := unsafe.Pointer(&(*(*[]byte)(unsafe.Pointer(&s)))[0])

或者因为数据指针在前,你可以单独使用一个uintptr

p := unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&s)))

https://play.golang.org/p/ps1Py7Ax6QK

None 这些方式保证在所有情况下都有效,或者在 Go 的未来版本中,并且 none 选项将保证空终止字符串。

最好的、受支持的选项是在 cgo 序言中创建一个垫片以接受 go 字符串,并将其转换为 *char。 CGO 提供访问以下功能来执行此操作:

const char *_GoStringPtr(_GoString_ s);

请参阅文档中的 Go references to C 部分。