我需要以某种方式为每个静态库和使用它们的项目定义模块名称。我不能简单地这样做:
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上测试
最佳答案
具有外部链接的实体在一个程序中只能有一个定义,因此在一个程序中不能对同一函数有多个定义也就不足为奇了。
这与内联无关,发生的情况是链接器看到同一符号的多个定义(这通常发生在模板实例化和内联函数以及使用动态库时的其他符号中)并选择一个定义来使用。 p>
要使每个库都有单独的定义,您需要它们具有内部链接,这可以通过将函数设置为静态或将其放入未命名的命名空间中,或使用特定于平台的方法(例如__dllimport
)来完成。或__attribute((visibility("hidden")))
告诉编译器该符号是共享库私有(private)的,不应导出(因此不会被同一符号的另一个定义替换。)
或者,只需将每个模块放在自己的命名空间中,并将函数放在该命名空间中,那么每个函数都是不同的,它们不会相互干扰。
关于c++ - 静态库中的内联函数被用户项目中的同名函数替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11433901/