Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is std::type_index safe across DLLs

Tags:

c++

c++11

dll

Let's say that I have a main DLL where there's a class like this:

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;
};

And I share an instance of that class through several DLLs. And in one of the DLLs I set some values like this:

template < typename T > struct Dummy
{

};

void InitFunc(Test * t)
{
    t->SetValue< Dummy<int> >(32);
    t->SetValue< Dummy<char> >(10);
    t->SetValue< Dummy<float> >(27);
}

And in another DLL I attempt to get those values using the same Dummy type. Would I get those same values or 0?

like image 999
SLC Avatar asked Sep 27 '22 01:09

SLC


1 Answers

This hugely depends on your definition of 'safe' and your deployment environment.

The crux of the argument of @SergeyA's answer is that the compiler generates std::type_info objects in each compilation unit - which are then coalesced by the linker when each DLL is linked.

Whilst a std::type_info will have an interface defined by the standard, the implementation (and particularly, storage layout) is an implementation detail that may change between compilers, compiler versions, and compiler options.

Furthermore from 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'

So now, we're relying on a several definitions of pointers into each DLL as well.

Thinking of some of the things you might do with a std::type_index - there's a high likelihood the results will be context dependent - largely dependant on where they are called from.

Now onto the question: Is this safe? Likely not. As a general rule, you should avoid exposing almost all of the std library (and particularly STL containers) across DLL interface boundaries.

If you do insist on doing so, it's only ever got a change of work in these very limited circumstances:

  • All components are built with precisely the same compiler
  • All components are built with precisely the same compiler options (debug vs release has always been a massive issue on Windows)
  • All components are deployed together as one unit
  • None of the components exposes an API to anybody else

This is actually true of a great deal of commercial software, and you'll find it is done more often than you think, but I wouldn't recommend it.

like image 174
marko Avatar answered Oct 13 '22 00:10

marko