【发布时间】:2017-04-27 09:06:13
【问题描述】:
我需要将一个大块的 float32(或字节)从 C 传递到 go 库。
代码如下:
package main
import (
"C"
"fmt"
)
//export PrintInt
func PrintInt(x []float32) {
fmt.Println(x)
}
func main() {}
用go build -buildmode=c-archive foo.go编译后
我收到了foo.h,这是其中的一部分:
typedef GoInt64 GoInt;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
#endif
/* End of boilerplate cgo prologue. */
#ifdef __cplusplus
extern "C" {
#endif
extern void PrintInt(GoSlice p0);
#ifdef __cplusplus
}
#endif
您可以看到foo.h 中的类型GoSlice 持有指向数据的指针(void *data)。那么PrintInt 在foo.h 中的实现是否会隐式复制该数据?
【问题讨论】:
-
如何将切片从 C 传递到 Go?如果你在 C 中创建切片头,答案应该很明显,因为切片头包含指向底层数组的指针。
-
@JimB 你可能是对的,这是最合理的实现。但是接口并没有禁止实现复制。
-
不会发生这种情况。 C 和 Go 都不会隐式分配新内存、复制相关数组并将 不同 值传递给函数。 Go 在所有情况下都是按值传递的,这里的值是切片头,没有别的。
-
@JimB "C 和 Go 都不会隐式分配新内存" 你能告诉我这是否记录在某处吗?我想确定下次遇到类似问题时。
-
我认为如果内存被复制,结构会有所不同,因为指针值必须改变。将值传递给函数并让函数接收 不同 值会很奇怪。您是否期望传递一个普通指针来取消引用并递归复制每个值,然后以某种方式在函数中接收一个新指针?一种语言实现可以做的事情有无数种,但并不是每一种可能性都可以记录下来。