【问题标题】:Global variables in library that linked by multiple entities of a single process由单个进程的多个实体链接的库中的全局变量
【发布时间】:2016-06-07 12:41:33
【问题描述】:

我有一个提供记录器服务的静态库,它链接到我的 C/C++ 项目中的几个子组件。

我想将logger 中定义的全局变量的范围设置为链接此库的所有实体(例如,log_level),我想知道将库更改为动态是否可以诡计……会吗?

【问题讨论】:

  • 您似乎以非标准方式使用“范围”一词,当然“设置全局变量的范围”的概念毫无意义。全局变量的作用域是全局的,这就是为什么它是一个 global 变量。
  • 所以,如果我理解正确,您希望共享单例 logger 实例的特定库具有不同的 log_level 值吗?对于这种情况,共享库不会改变任何东西。
  • @MSalters,我想你是对的,但我想强调的是,如果我将静态库链接到我的流程中的多个组件,它将为每个此类组件生成该库的单独实例,并且不启用共享全局变量。
  • @πάνταῥεῖ,我实际上希望进程中所有组件的日志级别相同。这就是为什么我想与与我的记录器库链接的所有组件共享 log_level
  • @Zohar81:如果它真的是一个全局变量,那应该已经是这样了。这就是为什么一个好的问题具有重现问题所需的最少代码的原因。你能构造一个libFooLibBar 使得每个都有自己的libLog::logLevel 吗?

标签: c++ c shared-libraries static-libraries


【解决方案1】:

您的问题没有明确您所说的“组件”和“范围”是什么意思。

如果我理解正确,您有一个程序(即单个可执行文件和运行时的单个进程),其中包括多个库(您称之为“组件”)并且 [其中一些] 这些库链接到一个公共 @987654321 @ 图书馆。您希望所有这些库都能够设置在logger 库中定义的公共变量log_level。我的理解正确吗?

如果您在logger 库的源代码中将log_level 定义为全局变量(即在任何函数范围之外定义一次),您将可以在任何其他组件/库中访问此全局变量通过将其声明为 extern 来链接到您的程序。

@MSalters,我想你是对的,但我想强调的是,如果我将静态库链接到我的进程中的多个组件,它将为每个此类组件生成该库的单独实例,并且不允许共享全局变量。 – Zohar81 昨天

不,最终链接将删除同一库的任何重复项。您可以将logger 库链接到程序一次或多次链接到每个组件/库(最终链接到程序),同一个变量log_level 将在所有人之间共享。

// logger.lib : logger.h
extern int log_level;
extern void log(const char* mesg);

 

// logger.lib : logger.c
int log_level;
void log(const char* mesg)    { /*...*/ }

 

// component1.lib : component1.c
#include "logger.h"  // declare log_level as extern
void component1()
{
    log_level = 1;   // modifies log_level defined in logger.c
    /* ... */
}

做同样事情的另一种(更好的)方法是将 log_level 变量定义为静态并提供某种访问器,例如:

// logger.lib : logger.h
extern void set_log_level(int log_level);
extern void log(const char* mesg);

 

// logger.lib : logger.c
static int s_log_level;  // only visible to logger.c
void set_log_level(int log_level) { s_log_level = log_level; }
void log(const char* mesg)        { /*...*/ }

【讨论】:

  • 感谢您的全面回答。只是为了确保,如果我希望每个加载 'logger' 库的组件的参数 'log_level' 都是唯一的,该怎么办?在这种情况下我应该如何实施它?再次感谢!
  • @Zohar81:“组件”是指“静态库”,“加载”是指“静态链接”到记录器库吗?如果所有这些库都链接到单个可执行文件,则无需关心多重链接“记录器”,log_level 变量将是唯一的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多