为了账号安全,请及时绑定邮箱和手机立即绑定

有没有一种安全的方法可以使用 CGo 从 C 代码中保留对 Go 变量的引用?

有没有一种安全的方法可以使用 CGo 从 C 代码中保留对 Go 变量的引用?

Go
紫衣仙女 2021-07-09 14:11:52
当使用 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 端控制变量的垃圾收集。

希望有帮助。


查看完整回答
反对 回复 2021-07-12
  • 1 回答
  • 0 关注
  • 240 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信