function template methods and DLL exports

A

Alfonso Morra

I have a class declared as ff:

class __declspec(dllexport) A {
public:
A() ;
A(const A&)
A& operator=(const A&) ;
~A() ;

void doThis(void) ;
void doThat(void) ;
template <class T> T doTheOther( const &T, int ) ;

private:
std::string s ;
std::vector< <std::pair> > vp ;
......
};


When I compile the code, the compiler generates several warnings such as:

warning C4251: 'A::s' : class 'std::basic_string<_Elem,_Traits,_Ax>'
needs to have dll-interface to be used by clients of class 'A'
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]

etc. Why do I have to export private variables (is that what the warning
message is instructing me to do?)

Despite the warnings, the code builds and the dll is built. When I use
the dll in another project, problems (unsuprisingly) arise but they are
of a slightly different kind. The function template method doTheOther
does not seem to be exported and I am getting a link error when I try to
link to A.lib so I can create a project that uses classes exported by A.dll

I have two questions:

1). Why do I need to decorate the private variables with
__declspec(dllexport) - as per compiler warnings?

2). Why is the method function template not getting exported (how do I
export the method in the DLL) ?


Thanks
 
T

Tamas Demjen

Alfonso said:
warning C4251: 'A::s' : class 'std::basic_string<_Elem,_Traits,_Ax>'
needs to have dll-interface to be used by clients of class 'A'
with
[
_Elem=char,
_Traits=std::char_traits<char>,
_Ax=std::allocator<char>
]

You may also want to read
http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
Although I didn't have a linker error problem related to exporting STL
classes. ("Workaround 2 can cause link errors..." doesn't seem to happen
to me). Be cautious, though. Also, the macros on this site don't work at
all. They may be for a very old version of VC++.

As an experiment, I worked out a small set of macros for exporting STL
containers, if you're interested. It's been tested with VC++ 2005 Beta 2
so far, but should also work with VC++ 2003. You definitely need to
modify it for different STL implementations. It's very compiler / STL
specific, thus the #if defined(_MSC_VER).

#ifndef DllExportH
#define DllExportH

#if defined(_MSC_VER)

#ifdef _DEBUG
# define class_it_base class
#else
# define class_it_base struct
#endif

#define EXPORT_STL_VECTOR(declspec_, T_) \
template class declspec_ std::allocator<T_ >; \
template class declspec_ std::vector<T_ >;

#define EXPORT_STL_VECTOR_CONST_ITERATOR(declspec_, T_) \
class_it_base declspec_ std::_Iterator_base; \
template class declspec_ std::_Vector_const_iterator<T_,\
std::allocator<T_ > >;

#define EXPORT_STL_DEQUE(declspec_, T_) \
template class declspec_ std::allocator<T_ >; \
template class declspec_ std::allocator<T_* >; \
template class declspec_ std::deque<T_ >;

#define EXPORT_STL_LIST(declspec_, T_) \
template class declspec_ std::allocator<T_ >; \
template class declspec_ std::allocator<std::_List_nod<T_,\
std::allocator<T_ > >::_Node>; \
template class declspec_ std::allocator<std::_List_nod<T_,\
std::allocator<T_ > >::_Node*>; \
template class declspec_ std::list<T_ >;

#define EXPORT_STL_SET(declspec_, T_) \
template class declspec_ std::allocator<T_ >; \
template struct declspec_ std::less<T_ >; \
template class declspec_ std::allocator<std::_Tree_nod< \
::_Node>; \
template class declspec_ std::allocator<std::_Tree_ptr< \
::_Node*>; \
template class declspec_ std::set<T_ >;

#define EXPORT_STL_MULTISET(declspec_, T_) \
template class declspec_ std::allocator<T_ >; \
template struct declspec_ std::less<T_ >; \
template class declspec_ std::allocator<std::_Tree_nod< \
::_Node>; \
template class declspec_ std::allocator<std::_Tree_ptr< \
::_Node*>; \
template class declspec_ std::multiset<T_ >;

#define EXPORT_STL_MAP(declspec_, K_, V_) \
template struct declspec_ std::less<K_ >; \
template class declspec_ std::allocator<std::_Tree_nod< \
std::_Tmap_traits<K_, V_, std::less<K_ >, \
std::allocator<std::pair<const K_, V_ > >, false> >::_Node>; \
template class declspec_ std::allocator<std::_Tree_nod< \
std::_Tmap_traits<K_, V_, std::less<K_ >, \
std::allocator<std::pair<const K_, V_ > >, false> >::_Node*>; \
template class declspec_ std::allocator<std::pair<const K_, V_ > >; \
template class declspec_ std::map<K_, V_ >;

#define EXPORT_STL_MAP_CONST_ITERATOR(declspec_, K_, V_) \
class_it_base declspec_ std::_Iterator_base; \
template class declspec_ std::_Tree<std::_Tmap_traits<K_, V_, \
::const_iterator;


#define EXPORT_STL_MULTIMAP(declspec_, K_, V_) \
template struct declspec_ std::less<K_ >; \
template class declspec_ std::allocator<std::_Tree_nod< \
std::_Tmap_traits<K_, V_, std::less<K_ >, \
std::allocator<std::pair<const K_, V_ > >, true> >::_Node>; \
template class declspec_ std::allocator<std::_Tree_nod< \
std::_Tmap_traits<K_, V_, std::less<K_ >, \
std::allocator<std::pair<const K_, V_ > >, true> >::_Node*>; \
template class declspec_ std::allocator<std::pair<const K_, V_ > >; \
template class declspec_ std::multimap<K_, V_ >;

#else

#define EXPORT_STL_VECTOR(declspec_, T_)
#define EXPORT_STL_VECTOR_CONST_ITERATOR(declspec_, T_)
#define EXPORT_STL_DEQUE(declspec_, T_)
#define EXPORT_STL_LIST(declspec_, T_)
#define EXPORT_STL_SET(declspec_, T_)
#define EXPORT_STL_MULTISET(declspec_, T_)
#define EXPORT_STL_MAP(declspec_, K_, V_)
#define EXPORT_STL_MAP_CONST_ITERATOR(declspec_, K_, V_)
#define EXPORT_STL_MULTIMAP(declspec_, K_, V_)

#endif

#endif
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top