英文:
Free C pointer when collected by GC
问题
我有一个与C库进行交互的包。现在我需要在Go结构体中存储一个指向C结构体的指针。
type A struct {
s *C.struct_b
}
显然,在结构体被GC回收之前,这个指针需要被释放。我该如何实现这个?
英文:
I have a package that interfaces with a C library. Now I need to store a pointer to a C struct in the Go struct
type A struct {
s *C.struct_b
}
Obviously this pointer needs to be freed before the struct is collected by the GC. How can I accomplish that?
答案1
得分: 5
最好的做法是在可能的情况下将C结构体复制到Go控制的内存中。
var ns C.struct_b
ns = *A.s
A.s = &ns
显然,这种方法并不适用于所有情况。C.struct_b可能过于复杂或与仍在C代码中的某些内容共享。在这种情况下,您需要创建一个.Free()或.Close()方法(哪个更合理就使用哪个),并记录用户必须调用该方法来使用您的结构体。在Go中,Free方法应始终是安全的调用。例如,在运行free之后,请确保将A.s设置为nil,以便如果用户调用了两次Free,程序不会崩溃。
还有一种方法可以创建finalizers。请参见我在这里写的另一个答案这里。然而,它们可能并不总是运行,如果垃圾创建得足够快,很可能垃圾的创建速度会超过收集速度。这应该被视为具有Free/Close方法的补充,而不是替代品。
英文:
The best thing to do is when possible copy the C struct into go controlled memory.
var ns C.struct_b
ns = *A.s
A.s = &ns
Obviously, that won't work in all cases. C.struct_b may be too complicated or shared with something still in C code. In this case, you need to create a .Free() or .Close() method (whichever makes more sense) and document that the user of your struct must call it. In Go, a Free method should always be safe to call. For example, after free is run, be sure to set A.s = nil so that if the user calls Free twice, the program does not crash.
There is also a way to create finalizers. See another answer I wrote here. However, they may not always run and if garbage is created fast enough, it is very possible that the creation of garbage will out pace collection. This should be considered as a supplement to having a Free/Close method and not a replacement.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论