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?
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With