當使用 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 分配的內存。最重要的考慮是不限制未來的實現(xiàn),所以規(guī)則是 Go 代碼可以傳遞一個指向 C 代碼的 Go 指針,但必須單獨安排 Go 掛起對指針的引用,直到 C 完成它。
所以我不確定你是否可以從 C 端固定變量,但你可以通過使用該runtime.SetFinalizer
函數從 Go 端控制變量的垃圾收集。
希望有幫助。
- 1 回答
- 0 關注
- 257 瀏覽
添加回答
舉報
0/150
提交
取消