如何将 C 函数中的字符串读入 Go?

How to read a string from a C function into Go?

我正在尝试使用 cgo 从 Go 调用 C 函数来读取错误消息。该函数生成一条小于 256 字节的未知长度消息。

C 中的工作示例:

char message[ERROR_SIZE]; //256
last_error( message, sizeof(message) );         
printf( "message: %s\n", message );

我在 Go 中的尝试(不工作):

var ptr *C.char
C.last_error(ptr, ERROR_SIZE)
var message = C.GoString(ptr)
fmt.Printf("message: %s\n", message)

go代码为运行时,消息为空。 go版本是否需要为消息预分配space?如何做到这一点?


LP 评论后更新以传递数组。这行得通,但似乎有点尴尬:

var buf [ERROR_SIZE]byte
var ptr = (*C.char)(unsafe.Pointer(&buf[0]))
C.last_error(ptr, len(buf))
var message = C.GoString(ptr)
fmt.Printf("message: %s\n", message)

有没有更简单的方法?

在您的第一个示例中,您传递了一个 nil 指针,因此没有为 C.last_error 分配内存来写入输出(幸运的是,它似乎什么都不做)。

您需要以某种方式分配内存,在 Go 中最直接的方法是使用切片,而不是创建具有静态大小的数组。

buf := make([]byte, ERROR_SIZE)
C.last_error((*C.char)(unsafe.Pointer(&buf[0])), len(buf))

// While C.GoString will find the terminating null if it's there, 
// there's no reason to copy the string in C, and allocate another slice.
if i := bytes.IndexByte(buf, 0); i >= 0 {
    buf = buf[:i]
}

fmt.Printf("message: %s\n", buf)