我需要以某种方式为每个静态库和使用它们的项目定义模块名称。我不能简单地这样做:
std::string const module_name = "my module";
因为我在静态成员初始化期间需要这个值。由于未定义静态数据初始化顺序,因此在我尝试使用它时,我的module_name
变量仍然可以保持未初始化状态。
为了解决这个问题,我定义了
inline std::string const& module_name()
{
static std::string const name = "my module";
return name;
}
每个模块。但这不起作用,因为所有module_name()
调用都被解析为使用父模块的实现(module_name()
总是返回父可执行项目的名称)。我不明白为什么。我希望由于这个内联函数是在静态库中定义和使用的,因此应该捕获实际的模块名称。是因为这个函数没有被编译器内联吗?
有什么建议的方法可以解决这个问题吗?
编译器:VC ++ 10和gcc,在VC ++ 10上测试
答案 0 :(得分:2)
具有外部链接的实体在程序中只能有一个定义,因此在一个程序中不能对同一个函数进行多个定义就不足为奇了。
这与内联无关,发生的事情是链接器看到同一符号的多个定义(通常在模板实例化和内联函数中发生,在使用动态库时会发生其他符号)并选择一个定义来使用。
要使每个库具有单独的定义,您需要它们具有内部链接,这可以通过使函数静态或将其放入未命名的命名空间,或使用特定于平台的方法(如__dllimport
或__attribute((visibility("hidden")))
告诉编译器该符号对于共享库是私有的,不应该被导出(因此不会被同一符号的另一个定义替换。)
或者,只需将每个模块放在自己的命名空间中并将该函数放在该命名空间中,然后每个函数都不同,它们不会干扰。