Is there a graceful way to pass large byte slice or io.Reader to c through cgo without memory copy?

huangapple go评论137阅读模式
英文:

Is there a graceful way to pass large byte slice or io.Reader to c through cgo without memory copy?

问题

我有一个需要大量数据的C程序。

假设我在Go语言中有一个4GB的字节切片,刚刚从一个大文件、互联网或套接字中加载进来。

然后我想将它传递给cgo。如果我传递一个指向字节缓冲区的指针,那么缓冲区仍然在Go语言中,因为缓冲区可能会被垃圾回收,从而在C端创建段错误。而且io.Reader不能简单地传递给cgo,因为它太通用了。

我知道我可以传递文件路径,或者在C中编写互联网请求代码来避免使用cgo传递字节。但这不方便,我仍然希望保持使用Go语言的便利性。

那么我们如何优雅地处理cgo中的大字节传递呢?如果没有其他选择,我想确保没有其他选择。

英文:

I have a c program that needs a lot of data to work.

Suppose I have a byte slice of 4GB in go, just loaded from a large file, or internet, or socket.

Then I want to pass it to cgo. If I pass a pointer to the byte buffer, the buffer is still in go, because the buffer can be garbage collected, and thus create segment fault in C side. And io.Reader cannot be simply passed to cgo beacuse it's too general.

I know I can pass the filepath, or write internet request code in C to avoid a cgo bytes pass. But that is not convenient, I still want to keep the advantage of convenience of golang.

So how can we gracefully handle large bytes pass in cgo? If there is no another option, I want to make sure there is no another option.

答案1

得分: 1

如果我传递一个指向字节缓冲区的指针,那么缓冲区仍然在Go语言中,因为缓冲区可能会被垃圾回收,从而在C语言中导致段错误。

只要C函数在调用返回后不再引用该指针,你是可以安全地将Go指针传递给C的。Go编译器会在C调用的持续时间内将分配固定在原地。

详细信息请参考https://pkg.go.dev/cmd/cgo#hdr-Passing_pointers。

英文:

> If I pass a pointer to the byte buffer, the buffer is still in go, because the buffer can be garbage collected, and thus create segment fault in C side.

You can safely pass a Go pointer to C, as long as the C function does not refer to that pointer any more after the call returns. The Go compiler will pin the allocation in place for the duration of the C call.

See https://pkg.go.dev/cmd/cgo#hdr-Passing_pointers for the precise details.

huangapple
  • 本文由 发表于 2021年10月18日 20:15:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/69615892.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定