2

我正在尝试在 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)

声明name(和nBufSize )的正确方法是什么?如何将name转换为 Go字符串?上面的代码没有按我的预期工作。它打印:

VM 1024 name: ""
... 

C API 文档,摘录

PrlFoundVmInfo_GetName - 参数

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

完整的文档可在C API 文档 - PrlFoundVmInfo_GetName 获得

4

2 回答 2

3

命令 cgo

转到 C 的引用

一些特殊函数通过复制数据在 Go 和 C 类型之间进行转换。在伪 Go 定义中:

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

Go 博客:C? 去?加油!

于 2014-02-01T21:54:15.533 回答
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)
于 2014-02-09T11:14:34.617 回答