Re: passing stl through dll
Alex Blekhman wrote:
[...]
There are two ways to solve it:
1. Easy way. Just disable C4251 warning alltogether. It's a bit
dirty solution, but it works with VC++. Eventually, both EXE and
DLL will use `std::string' instantiation from "msvcpXX.dll".
2. Hard way. First of all, define _STATIC_CPPLIB for the project.
It will tell the compiler to instantiate standard templates from
headers instead of picking them up from "msvcpXX.dll". Then, by
using trial and error method, add relevant instantiations in your
DLL header file. For example, if you want to use
`std::vector<std::string>' members in your exported class, then
you have to add the following exported instantiations:
class STL_API std::_String_base;
class STL_API std::_Container_base_secure;
template class STL_API std::allocator<char>;
template class STL_API std::basic_string<char>;
template class STL_API std::allocator<std::basic_string<char> >;
template class STL_API std::vector<std::basic_string<char> >;
class STL_API MyClass
{
public:
...
private:
std::vector<std::string> m_v;
};
Now you will be able to compile it without C4251 and link
successfully.
Thanks Alex - the 1. Easy way did not work for me as I already disabled
C4251 conditionally (for the STL includes, typedefs, declarations and
defines). So I tried 2. Hard way, which works fine for <vector> and the
<string> stuff but I'm struggling with <hash_map>. First some things to
hopefully understand template things better:
1. The define _STATIC_CPPLIB has to be placed in the DLL project and
also in the client EXE project? I've done so.
2. What does template instantiation exactly mean? Is it just a
definition of an interface to a specific class with all requested types
filled in? Does it produce any binary code (as it is said that no
objects are created)?
3. the lines:
template class STL_API std::allocator<std::basic_string<char> >;
template class STL_API std::vector<std::basic_string<char> >;
are conditionally prepended with "extern" in the reference doc
http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html -
you did not differentiate between "extern" and "auto" for EXE and DLL
code. Is it OK to instantiate the templates in both cases?
For <hash_map> it is hard to find the instantiations necessary for the
compiler - I get C4251's again in the EXE code beside the warning
suppression already done. I have:
#include <hash_map>
using namespace std;
typedef class STL_API allocator<int> cl_iAlloc_t;
typedef hash_multimap<byte, DWORD> STL_API CBDMapStd;
typedef pair <byte, DWORD> op_BDMap_t; // operand type
EXPIMP_STL template class STL_API allocator<DWORD>;
EXPIMP_STL template class STL_API allocator<op_BDMap_t>;
EXPIMP_STL template class STL_API hash_multimap<byte, DWORD>;
class STL_API CBDMapSup : public CBDMapStd
{
public:
CBDMapSup(void);
virtual ~CBDMapSup(void);
public:
void Add(byte byTag, DWORD dwValue);
DWORD Find(byte byTag) const;
DWORD FindKey(DWORD dwValue) const;
void Clear(void);
};
////
And I get these three different warnings:
....\Vc7\include\hash_map(154) : warning C4251:
'std::_Hmap_traits<_Kty,_Ty,_Tr,_Alloc,_Mfl>::comp' : class
'std::hash_compare<_Kty,_Pr>' needs DLL interface used for clients of
class 'std::_Hmap_traits<_Kty,_Ty,_Tr,_Alloc,_Mfl>'
with
[
_Kty=byte,
_Ty=DWORD,
_Tr=std::hash_compare<byte,std::less<byte>>,
_Alloc=std::allocator<std::pair<const byte,DWORD>>,
_Mfl=true
]
and
[
_Kty=byte,
_Pr=std::less<byte>
]
and
[
_Kty=byte,
_Ty=DWORD,
_Tr=std::hash_compare<byte,std::less<byte>>,
_Alloc=std::allocator<std::pair<const byte,DWORD>>,
_Mfl=true
]
s:\ffmpeg\lshared\include\MPEG2Supp.h(57) : see instantiation
of compiled template 'std::hash_multimap<_Kty,_Ty,_Tr,_Alloc>'
with
[
_Kty=byte,
_Ty=DWORD,
_Tr=std::hash_compare<byte,std::less<byte>>,
_Alloc=std::allocator<std::pair<const byte,DWORD>>
]
....\Vc7\include\hash_map(154) : warning C4251: 'std::_Hash<_Tr>::_List'
: class 'std::list<_Ty,_Ax>' needs DLL interface used for clients of
class 'std::_Hash<_Tr>'
with
[
_Tr=std::_Hmap_traits<byte,DWORD,std::hash_compare<byte,std::less<byte>>,std::allocator<std::pair<const
byte,DWORD>>,true>
]
and
[
_Ty=std::_Hmap_traits<byte,DWORD,std::hash_compare<byte,std::less<byte>>,std::allocator<std::pair<const
byte,DWORD>>,true>::value_type,
_Ax=std::_Hmap_traits<byte,DWORD,std::hash_compare<byte,std::less<byte>>,std::allocator<std::pair<const
byte,DWORD>>,true>::allocator_type
]
and
[
_Tr=std::_Hmap_traits<byte,DWORD,std::hash_compare<byte,std::less<byte>>,std::allocator<std::pair<const
byte,DWORD>>,true>
]
....\Vc7\include\hash_map(154) : warning C4251: 'std::_Hash<_Tr>::_Vec' :
class 'std::vector<_Ty,_Ax>' needs DLL interface used for clients of
class 'std::_Hash<_Tr>'
with
[
_Tr=std::_Hmap_traits<byte,DWORD,std::hash_compare<byte,std::less<byte>>,std::allocator<std::pair<const
byte,DWORD>>,true>
]
and
[
_Ty=std::_Hash<std::_Hmap_traits<byte,DWORD,std::hash_compare<byte,std::less<byte>>,std::allocator<std::pair<const
byte,DWORD>>,true>>::iterator,
_Ax=std::allocator<std::pair<const
byte,DWORD>>::rebind<std::_Hash<std::_Hmap_traits<byte,DWORD,std::hash_compare<byte,std::less<byte>>,std::allocator<std::pair<const
byte,DWORD>>,true>>::iterator>::other
]
and
[
_Tr=std::_Hmap_traits<byte,DWORD,std::hash_compare<byte,std::less<byte>>,std::allocator<std::pair<const
byte,DWORD>>,true>
]
//--------//
Any suggestions about instantiation things for that lot stuff?
Regards,
Konran