有没有一种优雅的方法可以在没有内存复制的情况下通过 cgo 将大字节切片或 io.Reader 传递给 c?

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

我有一个需要大量数据才能运行的 c 程序。

假设我有一个 4GB 的字节片,刚从一个大文件、互联网或套接字加载。

那我想传给cgo。如果我传递一个指向字节缓冲区的指针,缓冲区仍然在 go 中,因为缓冲区可以被垃圾收集,从而在 C 端创建段错误。而且 io.Reader 不能简单地传递给 cgo 因为它太笼统了。

我知道我可以传递文件路径,或者用 C 编写互联网请求代码以避免 cgo 字节传递。但是那样也不方便,我还是想保留golang方便的优点。

那么如何才能优雅的处理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.

可以 安全地将 Go 指针传递给 C,只要 C 函数在调用 returns 后不再引用该指针。 Go 编译器将在 C 调用期间固定分配。

有关详细信息,请参阅 https://pkg.go.dev/cmd/cgo#hdr-Passing_pointers