当使用 CGo 将 C 代码与 Go 接口时,如果我在 C 端保留对 Go 变量的引用,我是否会冒该对象被垃圾收集器释放的风险,或者 GC 是否会看到由管理的变量中的指针? C面?为了说明我的要求,请考虑以下示例程序:去代码:package main/*typedef struct _Foo Foo;Foo *foo_new(void);void foo_send(Foo *foo, int x);int foo_recv(Foo *foo);*/import "C"//export makeChannelfunc makeChannel() chan int { return make(chan int, 1)}//export sendIntfunc sendInt(ch chan int, x int) { ch <- x}//export recvIntfunc recvInt(ch chan int) int { return <-ch}func main() { foo := C.foo_new() C.foo_send(foo, 42) println(C.foo_recv(foo))}代码:#include <stdlib.h>#include "_cgo_export.h"struct _Foo { GoChan ch;};Foo *foo_new(void) { Foo *foo = malloc(sizeof(Foo)); foo->ch = makeChannel(); return foo;}void foo_send(Foo *foo, int x) { sendInt(foo->ch, x);}int foo_recv(Foo *foo) { return recvInt(foo->ch);}foo->ch在foo_new和foo_send调用之间是否有被垃圾收集器释放的风险?如果是这样,有没有办法从 C 端固定 Go 变量以防止它在我持有对它的引用时被释放?
1 回答
千巷猫影
TA贡献1829条经验 获得超7个赞
根据gmp CGo 示例:
垃圾收集是个大问题。Go 世界拥有指向 C 世界的指针并在不再需要时释放这些指针是很好的。为了提供帮助,Go 代码可以定义包含 C 指针的 Go 对象,并在这些 Go 对象上使用 runtime.SetFinalizer。
C 世界有指向 Go 世界的指针要困难得多,因为 Go 垃圾收集器不知道 C 分配的内存。最重要的考虑是不限制未来的实现,所以规则是 Go 代码可以传递一个指向 C 代码的 Go 指针,但必须单独安排 Go 挂起对指针的引用,直到 C 完成它。
所以我不确定你是否可以从 C 端固定变量,但你可以通过使用该runtime.SetFinalizer
函数从 Go 端控制变量的垃圾收集。
希望有帮助。
- 1 回答
- 0 关注
- 240 浏览
添加回答
举报
0/150
提交
取消