我试图调用一个需要C字符串(char*
)的C函数。我知道cgo documentation中记录的C.CString
函数,但由于我调用的函数已经复制了,我试图避免使用Cstring
个版本。
现在,我正在这样做,s
是一个字符串
var cs *C.char = (*C.char)( unsafe.Pointer(& []byte(s) [0]))
但我觉得[]bytes(s)
正在制作自己的副本。是否可以获得char*
?
答案 0 :(得分:4)
如果你这样做的次数足以令人担忧,那么将数据保持在切片中是非常明智的。
如果您确实想要访问字符串的地址,可以使用unsafe包将其转换为与字符串标头匹配的结构。使用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
这些方法都不能保证在所有情况下或在Go的未来版本中都能正常工作,并且没有一个选项可以保证以空字符串结尾的字符串。
最好的,支持的选项是在cgo前导码中创建一个垫片以接受go字符串,并将其转换为*char
。 CGO提供对以下功能的访问:
const char *_GoStringPtr(_GoString_ s);
请参阅文档中的Go references to C部分。