c++ - std::type_index 跨 DLL 是否安全

标签 c++ c++11 dll

假设我有一个主 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/

相关文章:

dll - VB6:获取DLL的当前路径

c++ - 如何在 Visual Studio 操作中输出新行?

c++ - 在 Visual Studio 2015 中使用 QtAddIn 调试 Visual Studio 2013 运行时

c++ - 如何获取整数参数包中的第i个整数?

c++ - VS2012 bind2nd 不是 std 的成员

.net - 如何判断两个 .NET DLL 是否相同?

c - 关于将 windbg 用于从 Labview 调用的 dll 的问题

c++ - 是否有更简单的 Windows C++ Subversion API 或 minimal_client.c 的示例 .vcproj?

C++ 函数编译错误

c++ - 我如何 move std::unique_ptr 作为构造函数参数?