From: http://www.abstraction.net/ViewArticle.aspx?articleID=83
Related readings:
http://stackoverflow.com/questions/767579/exporting-classes-containing-std-objects-vector-map-etc-from-a-dll
http://www.cplusplus.com/forum/general/78467/
STL and DLLs
By George Mihaescu
This article is now obsolete: the described behavior applies only up to (and including) Visual Studio 5.0. After that version the STL and compiler implementations have changed so that the behavior described here is not an issue anymore.
Summary: this article describes potential problems when exporting from a DLL classes that are based on (or contain public members based on) STL types and provides a solution.
The use of various classes from STL in DLLs raises a major problem: STL template instantiations cannot be exported directly from the DLL, the main reason being the fact that a few of the STL templates make use of static members. By exposing in a header an STL template instantiation, the DLL and the user of the DLL (that includes the exposed header) get different copies of the static members, and this leads to unpredictable behavior and random crashes.
This problem is documented in the MSDN and various means to resolve it are described.
The most elegant manner of solving the problem is to provide wrapper classes for the STL template instantiations, and those wrappers are exported from the DLL, as shown below.
For instance, instead of exposing a header from a DLL like this:
#include <map> //for STL map
using namespace std;
class __declspec(dllexport) MyClass
{
};
typedef __declspec (dllexport) map <int, MyClass> AMap;
use a header like this:
#include <map> //for STL map
using namespace std;
class __declspec(dllexport) MyClass
{
};
//wrapper class for the map
class __declspec(dllexport) AMap
{
public:
AMap ();
~AMap ();
//wrapper methods for the aggregated map:
void Insert (const MyClass& m);
const MyClass* Find (int key);
private:
typedef map <int, MyClass> _AMap;
AMap m_map; //the wrapped map
};
When implementing the header exposed by the DLL this way, the compiler will generate a warning similar to “class std::map <int, MyClass> must have DLL interface to be used by clients of MyDll.dll”. This is usually with no consequences (it means that friends of the class AMap -if any- will not be able to directly access the wrapped map because it is not exported from the DLL). However, the direct usage of the map by clients of the DLL was not possible anyway due to the problem we were trying to solve in the first place - so this warning is of no concern.