【问题标题】:Golang object destructor for C/C++ bindings用于 C/C++ 绑定的 Golang 对象析构函数
【发布时间】:2018-12-21 12:37:22
【问题描述】:

我们正在使用 C/C++ 构建密码库,现在还添加了对 Golang 的支持。 CGO 绑定工作正常,除了一件事我们需要调用一些函数来手动从内存中释放 C 指针。 目前我们正在这样做,通过制作一些 Go 接口包装器来清理内存。

func SomeFunc() {
  cObj := NewObjectFromCPP()
  defer cObj.Free()
}

当 Golang GC 试图清理包装的对象时,我们还尝试使用 runtime.SetFinilizer 来清理内存。但事实证明,runtime.SetFinilizer 回调不是每次都运行,或者根本没有运行,因为在文档中它说 它最终会运行

在我看来,我们当前的解决方案很老套,希望从已经做过类似事情的人那里获得一些意见。

除了直接调用手动方法之外,从 Go 中清理 C/C++ 内存的正确方法是什么?

【问题讨论】:

  • This discussion may be helpful. 总之,终结器并非在所有情况下都可靠,因此除非您意识到它们的局限性,否则请改用手动管理,例如使用引用计数。

标签: go cgo


【解决方案1】:

Go 中处理超出范围的内容的约定是使用 defer(),就像你正在做的那样。

还有另一种约定是使用 Close() 作为您的处理方法,实际上库的许多部分都采用这种约定(例如 Closer)。

func doThings() {
    if thing, err := openThingHoldingResources(); err != nil {
        // TODO: Handle error
    }
    defer thing.Close()

    // TODO: Do stuff with thing
}

Go 的主要设计目标之一是将魔法保持在最低限度,而在对象生命周期事件(构造函数和析构函数)上自动调用的函数是他们回避的魔法之一。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 2016-12-28
    • 2011-12-14
    • 2023-03-15
    • 2023-03-27
    • 2010-09-30
    相关资源
    最近更新 更多