在Go中使用C库时,如何将UTF-8编码的char数组正确转换为Go字符串?

时间:2014-02-01 19:00:09

标签: utf-8 go parallels cgo

我正在尝试在Go中使用C库。 C.PrlFoundVmInfo_GetName函数将UTF-8编码的字符串写入名称,长度为 nBufSize

// PRL_CHAR sName[1024];
var sName [1024]C.PRL_CHAR
// PRL_UINT32 nBufSize = sizeof(sName);
var nBufSize C.PRL_UINT32 = C.PRL_UINT32(unsafe.Sizeof(sName))
ret = C.PrlFoundVmInfo_GetName(hFoundVmInfo, (*C.PRL_CHAR)(unsafe.Pointer(&sName)), &nBufSize)
// printf("VM name: %s\n", sName);
var gName string = C.GoString((*C.char)(unsafe.Pointer(&sName)))
fmt.Printf("VM %d name: \"%s\"\n", nBufSize, gName)

声明名称(以及 nBufSize )的正确方法是什么?如何将名称转换为Go 字符串< / em>的?上面的代码没有像我期望的那样工作。它打印:

VM 1024 name: ""
... 

C API文档,解压缩

PrlFoundVmInfo_GetName - 参数

PRL_RESULT PrlFoundVmInfo_GetName(
  PRL_HANDLE handle, 
  PRL_STR sName, 
  PRL_UINT32_PTR pnNameBufLength
);
  • 句柄 - 标识容器的PHT_FOUND_VM_INFO类型的句柄。
  • sName - [out]指向接收名称的缓冲区的指针。传递空指针以确定所需的缓冲区大小。
  • pnNameBufLength - [in]用于接收输出数据的缓冲区大小(以字节为单位)。 [out]缓冲区参数包含空指针或指定的缓冲区大小不够大时所需的缓冲区大小。

完整文档可在C API Documentation - PrlFoundVmInfo_GetName

获取

2 个答案:

答案 0 :(得分:3)

  

Command cgo

     

Go references to C

     

一些特殊功能通过制作转换Go和C类型   数据副本。在伪Go定义中:

// C string, length to Go string
func C.GoStringN(*C.char, C.int) string

The Go Blog: C? Go? Cgo!

答案 1 :(得分:0)

这是解决方案,创建一个字节数组并使 sName 指向它。使用后,使用C.GoStringN将内容转换为Go字符串。

var buf = make([]byte, 1024)
var sName C.PRL_STR = (C.PRL_STR)(unsafe.Pointer(&buf))
var nBufSize C.PRL_UINT32 = 1024
ret = C.PrlFoundVmInfo_GetName(*hFoundVmInfo, sName, &nBufSize)
gName := C.GoStringN((*_Ctype_char)(unsafe.Pointer(sName)), C.int(nBufSize))
fmt.Printf("VM %d name: \"%s\"\n", nBufSize, gName)