英文:
Does passing a slice to golang from c do a memory copy?
问题
我需要将一个大块的float32(或byte)数据从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
)。那么,在foo.h
中的PrintInt
实现是否对该数据进行了隐式复制?
英文:
I need to pass a big chunk for float32 (or byte) from C to a go library.
Here is the code:
package main
import (
"C"
"fmt"
)
//export PrintInt
func PrintInt(x []float32) {
fmt.Println(x)
}
func main() {}
After compile it with go build -buildmode=c-archive foo.go
I got foo.h
, here of a part of it:
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
You can see that type GoSlice
in foo.h
holds a pointer to the data (void *data
). So does the implementation of PrintInt
in foo.h
do an implicit copy of that data?
答案1
得分: 3
我尝试在Go端修改数据,然后在C端进行反映。所以它们共享同一块内存。
foo.go:
package main
import (
"C"
"fmt"
)
//export PrintInt
func PrintInt(x []float32) {
fmt.Println(x)
for i := range x {
x[i] = -float32(i)
}
}
func main() {}
foo.c:
#include <stdio.h>
#include "foo.h"
int main() {
float bar[32];
for(int i = 0; i < 32; i++) {
bar[i] = i;
}
GoSlice s;
s.data = (void*)bar;
s.len = 32;
s.cap = 32;
PrintInt(s);
for(int i = 0; i < 32; i++) {
printf("%f ", bar[i]);
}
return 0;
}
使用以下命令编译和运行:
go build -buildmode=c-archive foo.go
cc foo.c foo.a -o 123 && ./123
我得到的输出是:
[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
26 27 28 29 30 31]
-0.000000 -1.000000 -2.000000 -3.000000 -4.000000 -5.000000 -6.000000 -7.000000 -8.000000 -9.000000 -10.000000 -11.000000 -12.000000 -13.000000 -14.000000 -15.000000 -16.000000 -17.000000 -18.000000 -19.000000 -20.000000 -21.000000 -22.000000 -23.000000 -24.000000 -25.000000 -26.000000 -27.000000 -28.000000 -29.000000 -30.000000 -31.000000
英文:
I tried to modify the data from go side, it is reflected in C. So they share same memory.
foo.go:
package main
import (
"C"
"fmt"
)
//export PrintInt
func PrintInt(x []float32) {
fmt.Println(x)
for i := range x {
x[i] = -float32(i)
}
}
func main() {}
foo.c:
#include <stdio.h>
#include "foo.h"
int main() {
float bar[32];
for(int i = 0; i < 32; i++) {
bar[i] = i;
}
GoSlice s;
s.data = (void*)bar;
s.len = 32;
s.cap = 32;
PrintInt(s);
for(int i = 0; i < 32; i++) {
printf("%f ", bar[i]);
}
return 0;
}
With command:
go build -buildmode=c-archive foo.go
cc foo.c foo.a -o 123 && ./123
I got output:
> [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
> 26 27 28 29 30 31]
> -0.000000 -1.000000 -2.000000 -3.000000 -4.000000 -5.000000 -6.000000 -7.000000 -8.000000 -9.000000 -10.000000 -11.000000 -12.000000 -13.000000 -14.000000 -15.000000 -16.000000 -17.000000 -18.000000 -19.000000 -20.000000 -21.000000 -22.000000 -23.000000 -24.000000 -25.000000 -26.000000 -27.000000 -28.000000 -29.000000 -30.000000 -31.000000
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论