2

我需要以某种方式为我的每个静态库和使用它们的项目定义模块名称。我不能简单地这样做:

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 上测试

4

1 回答 1

2

具有外部链接的实体在程序中只能有一个定义,因此在一个程序中不能对同一函数有多个定义也就不足为奇了。

这与内联无关,发生的情况是链接器看到同一个符号的多个定义(这通常发生在模板实例化和内联函数以及使用动态库时的其他符号中)并选择一个定义来使用。

要使每个库都有一个单独的定义,您需要它们具有内部链接,这可以通过使函数静态或将其放在未命名的命名空间中或使用特定于平台的方法(例如__dllimport__attribute((visibility("hidden")))告诉编译器符号是私有的)来完成到共享库并且不应该被导出(因此不会被相同符号的另一个定义替换。)

或者,只需将每个模块放在自己的命名空间中,并将函数放在该命名空间中,然后每个函数都是不同的,它们不会干扰。

于 2012-07-11T13:52:14.010 回答