gpt4 book ai didi

使用CGo调用带有双指针输出参数的C函数

转载 作者:IT王子 更新时间:2023-10-29 01:40:51 26 4
gpt4 key购买 nike

我正在尝试找出调用 this function 的正确方法:

size_t
fz_buffer_storage(fz_context *ctx, fz_buffer *buf, unsigned char **datap)
{
if (datap)
*datap = (buf ? buf->data : NULL);
return (buf ? buf->len : 0);
}

使用 CGo 获取底层字符串及其长度作为 Go 中的字节数组。

这是正确的做法吗?

var bufferContents *C.uchar
length := C.fz_buffer_storage(ctx, buf, &bufferContents)
bytes := C.GoBytes(unsafe.Pointer(bufferContents), C.int(length))

由于 C 代码覆盖了 *datap,我不确定垃圾收集器是否仍会做正确的事情。

我看到了一个答案here提出一些类似的建议

var tempUcharPtr *C.uchar
bufferContents := C.malloc(C.size_t(unsafe.Sizeof(tempUcharPtr)))
defer C.free(bufferContents)
length := C.fz_buffer_storage(ctx, buf, (**C.uchar)(bufferContents))
bytes := C.GoBytes(unsafe.Pointer(*(**C.uchar)(bufferContents)), C.int(length))

这似乎也有效,但它更复杂,我想知道它是否比以前的版本更好/更安全。

最佳答案

显然,第一个版本没问题。引用 the docs :

Go code may pass a Go pointer to C provided the Go memory to which it points does not contain any Go pointers.

据我了解,由于 var bufferContents *C.uchar 将被初始化为 nil,因此它不算作上述规则的“Go 指针”。以下简化的代码示例证实了这一点:

package main

// void F(char **p) {}
import "C"

func main() {
var p *C.char = new(C.char)
C.F(&p)
}

将触发“ panic :运行时错误:cgo 参数有指向 Go 指针的 Go 指针”

package main

// void F(char **p) {}
import "C"

func main() {
var p *C.char
C.F(&p)
}

即使设置 GODEBUG=cgocheck=2 也能正常工作。

感谢 Gophers Slack 社区的#cgo channel 上的人们帮助我理解了这一点!

关于使用CGo调用带有双指针输出参数的C函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51932020/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com