访问字符串的原始字节
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 部分。
我正在尝试调用一个 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 部分。