【问题标题】:Static variable inside shared library共享库中的静态变量
【发布时间】:2014-02-24 09:31:28
【问题描述】:

我的问题是关于在共享库中创建的静态变量 (static void*)(我们称这个库为“S”),但它是一个内部变量,未在外部显示,但每次调用 API 都依赖于它。现在让我们考虑一个案例,当一个程序(我们称之为主程序)链接到另外两个共享库并且每个共享库都与库 S 链接时。现在我们的主程序的这个静态变量会发生什么?它有一个实例吗?两个?

【问题讨论】:

  • 会有一个实例,因为您将其声明为静态实例
  • @Suma 回答你提到的问题对我有什么帮助?
  • 它的相关之处在于它展示了一个场景,其中链接到两个共享库 B 和 C 都静态链接到库 A 会导致 A 中的变量存在两次。
  • 在这种情况下没有静态链接。

标签: c static linker shared-libraries


【解决方案1】:

苏玛的回答是正确的。静态变量只有一个实例。这也是为什么在共享库中拥有静态全局变量可能是一个大问题。一个可能发生这种情况的真实示例:

  • Apache 网络服务器,它加载以下模块:
    • mod_php 链接到
      • libxml2
    • mod_perl 加载
      • libxml2

现在,如果某些 PHP 代码修改了全局设置,例如 libxml2 中的解析器选项,Perl 代码也会看到这些更改。这可能导致极难诊断的错误。因此,您应该不惜一切代价避免共享库中的全局状态。

(现在使用 libxml2,您可以在本地进行大多数设置。)

【讨论】:

    【解决方案2】:

    假设您的静态变量仅在一个翻译单元中定义,它只会存在一次,因为共享库仅在进程中加载​​一次。

    如果同时使用 sharedstatic 链接,这将变得更加困难。

    【讨论】:

      【解决方案3】:

      编译器为每个全局静态变量创建一个不同的实例,甚至当您有多个同名的此类变量时。

      事实上,编译器(或者可能是预处理器)会根据声明它的源文件的名称隐式更改每个此类变量的名称。

      您可以通过在头文件中声明一个全局静态变量来证明这一点,然后将此头文件包含在几个不同的源文件中。尝试在每个源文件中将其设置为不同的值,您会看到该变量在每个源文件中保留其不同的值。

      【讨论】:

      • 我认为这不是这个问题的意义所在。没有理由假设静态变量在代码中有多个定义。
      • @Suma:谢谢你的反对票。请尝试答案底部的建议,如果您证明我错了,我保证删除此答案!!!
      • 我理解你写的内容,你是正确的,但没有理由假设 OP 已经在标题或多个翻译单元中定义了变量。
      • ... 如果变量只定义一次,并且库只链接一次(它通常会链接一次,除非你混合静态/共享链接),那么只有一个变量的实例。
      • @Suma:我的回答一般解释了全局静态变量的概念。在头文件中声明它的目的仅仅是为了支持我提供的描述,并提出一种测试方法!!!
      猜你喜欢
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-23
      • 1970-01-01
      • 2016-04-17
      • 1970-01-01
      • 2011-03-24
      相关资源
      最近更新 更多