假设我有一个主 DLL,其中有一个这样的类:
class Test
{
public:
typedef std::unordered_map< std::type_index, int > Map;
template < typename T > void SetValue(int val)
{
SetValue(std::type_index(typeid(T)), val);
}
template < typename T > int GetValue()
{
return GetValue(std::type_index(typeid(T)));
}
protected:
// Defined in .cpp file
void SetValue(const std::type_index & idx, int val)
{
m_Map[idx] = val;
}
// Defined in .cpp file
int GetValue(const std::type_index & idx)
{
Map::const_iterator itr = m_Map.find(idx);
if (itr != m_Map.cend())
{
return itr->second;
}
return 0;
}
private:
Map m_Map;
};
我通过几个 DLL 共享该类的一个实例。在其中一个 DLL 中,我设置了一些值,如下所示:
template < typename T > struct Dummy
{
};
void InitFunc(Test * t)
{
t->SetValue< Dummy<int> >(32);
t->SetValue< Dummy<char> >(10);
t->SetValue< Dummy<float> >(27);
}
在另一个 DLL 中,我尝试使用相同的 Dummy
类型获取这些值。我会得到相同的值还是 0?
最佳答案
这在很大程度上取决于您对“安全”的定义和您的部署环境。
@SergeyA 的回答的关键在于,编译器在每个编译单元中生成 std::type_info
对象 - 然后在链接每个 DLL 时由链接器合并。
虽然 std::type_info
将具有标准定义的接口(interface),但实现(尤其是存储布局)是一个实现细节,可能会在编译器、编译器版本和编译器选项之间发生变化.
进一步来自 CppReference
The type_index class is a wrapper class around a std::type_info object, that can be used as index in associative and unordered associative containers. The relationship with type_info object is maintained through a pointer'
所以现在,我们也依赖于每个 DLL 中的多个指针定义。
想想您可能会用 std::type_index
做的一些事情 - 结果很可能会依赖于上下文 - 很大程度上取决于调用它们的位置。
现在问题来了:这安全吗?可能不会。作为一般规则,您应该避免跨 DLL 接口(interface)边界公开几乎所有的 std 库(尤其是 STL 容器)。
如果你坚持这样做,它只会在这些非常有限的情况下改变工作:
- 所有组件都是用完全相同的编译器构建的
- 所有组件都是使用完全相同的编译器选项构建的(调试与发布一直是 Windows 上的一个大问题)
- 所有组件作为一个单元一起部署
- 没有任何组件向任何其他人公开 API
实际上很多商业软件都是如此,您会发现这样做的频率比您想象的要高,但我不推荐这样做。
关于c++ - std::type_index 跨 DLL 是否安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34050429/