Exporting classes containing std:: objects (vector, map, etc) from a dll
2012-11-05 13:52
501 查看
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.
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.
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.
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 problem
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 anSTL 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 solution
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.
相关文章推荐
- std::vector sort containing classes
- std::map与std::vector
- c++11 container liber: std::queue std::map std::vector std::unique_ptr
- std::map与std::vector
- warning C4251: 'vectortemp::m_Vector' : class 'std::vector' needs to have dll-interface to be used by clients of class 'vectorte
- 有关std::map和std::vector的使用
- std::map与std::vector
- 【转】VC中的class“std::vector<_Ty>”需要有 dll 接口由 class“Test”的客户端使用错误
- std::map与std::vector
- std::map与std::vector
- warning C4251: “std::vector<_Ty>”需要有 dll 接口由 class“Test”的客户端使用错误
- std::vector传递dll参数异常-长度超限
- 关于容器的用法(vector,deque,list,set,map etc.)
- 使用std的vector,map,list, set等注意问题
- 跨dll/process时std::map中内存被破坏的处理方案
- std::map与std::vector
- Exporting C++ classes from a DLL
- LevelDB DLL for Windows - A New Approach to Exporting C++ Classes from a DLL
- 去除Warning C4251 “class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class
- std::map与std::vector