Go语言调用C结构体char数组变量时输出字节序列而非目标字符串的解决问询
How to correctly retrieve and display a string from a C struct's char array in CGO?
我明白你遇到的问题了——你期望输出字符串"Test",但得到的却是一堆ASCII数值的数组。这是因为Go并没有自动把C风格的char数组转换成Go字符串,而是直接打印了数组里的每个字节值。
问题原因
在CGO中,C的char a[10]会被Go映射为[10]C.char类型。当你直接打印这个数组时,Go会输出每个元素的ASCII数值(比如84对应'T',101对应'e'),而不是拼接成字符串。另外,C字符串是以\0结尾的,我们需要利用这一点来正确提取有效字符串。
解决方案
你可以使用CGO提供的C.GoString()函数,它能把C风格的字符串(以\0结尾的char*)转换成Go字符串。只需要把char数组的首元素指针传给这个函数即可。
修改你的main.go中的循环部分:
func main() { s := C.show() defer C.free(unsafe.Pointer(s)) sSlice := (*[1]C.struct_student)(unsafe.Pointer(s)) fmt.Println(sSlice) for _, ss := range sSlice { // 取char数组的首元素指针,用C.GoString转换为Go字符串 fmt.Printf("A...%s\n", C.GoString(&ss.a[0])) } }
另一种手动转换方式(可选)
如果你不想用C.GoString(),也可以手动把[10]C.char转换成Go的[]byte,再截断到第一个\0的位置:
import "strings" // ... for _, ss := range sSlice { // 把C.char数组转成Go的byte切片 byteSlice := (*[10]byte)(unsafe.Pointer(&ss.a[0]))[:] // 截断到第一个空字节的位置 str := strings.SplitN(string(byteSlice), "\x00", 2)[0] fmt.Printf("A...%s\n", str) }
这两种方式都能正确输出你期望的"Test"。第一种方式更简洁,是CGO处理C字符串的标准做法。
内容的提问来源于stack exchange,提问作者Alex Smith
相关产品推荐
相关产品推荐

