【问题标题】:Maintain the status of global variables of dynamic library in CGO维护CGO中动态库的全局变量状态
【发布时间】:2021-05-17 10:30:18
【问题描述】:

我通过使用 CGO 在 Go 代码中使用 C 库。问题是,似乎每次调用 C 函数时都没有维护全局变量的状态。

这个库有一个全局变量和一系列初始化函数。调用初始化函数没有效果。就好像每个函数执行后分配给库的整个内存都被清除了。并且每个函数都是独立执行的。

有没有人有这方面的经验我应该设置什么?

PS:我没有在 Go 中创建对这些全局变量的引用。此全局变量是尚未导出的结构。它的定义不在库的主 .h 中。有没有办法在不更改 C 库代码的情况下保留这个全局变量? (感谢:TehSphinX)

变量是:swed in https://www.astro.com/ftp/swisseph/src/sweph.h

extern TLS struct swe_data swed;

【问题讨论】:

  • 这完全不正常,但没有minimal reproducible example 就很难说更多了。
  • 你是否保留了对 Go 中那些全局变量的引用? Go GC 将清理 Go 未保留引用的任何内存。这可能会有所帮助:go101.org/article/unsafe.html。多说一句,我们需要看一些代码。

标签: c go global-variables cgo stateful


【解决方案1】:

您在声明中的TLS 表明C 库正在使用Thread Local Storage。这意味着有不止一个全局变量的实例。您所看到的是从不同的 C 语言级线程访问不同的实例如何导致访问不同的变量。

Go 的 goroutine 和 C 语言级别的线程之间没有定义的绑定。 Go 执行程序(“M”,在内部运行时,从一个 Go 版本更改为另一个版本)确实位于许多系统上的 POSIX 样式线程之上,但是一个 goroutine 可能会从一个线程跳到另一个线程,这是相当不可预测的。为了让 TLS 完全正常工作,您保证对 C 代码的调用会到达某个线程并停留在那里,直到 C 代码返回到 Go 代码。您无法保证并且无法控制的是此时运行哪个 C 线程。

您必须选择某种方式来坚持一个特定的 C 线程,或者破坏 TLS 设置,才能在此处取得任何进展。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    相关资源
    最近更新 更多