Using Template Classes and Functions in a Common Object / DLL

I am working on a much larger project that spans many shared libraries. We also rely heavily on STL, Boost, and our own template classes and functions. Many exported classes contain template members, and exported functions contain template parameters.

Here is a stripped down example of how I export the library:

#if defined(_MSC_VER) && defined(_DLL) // Microsoft #define EXPORT __declspec(dllexport) #define IMPORT __declspec(dllimport) #elif defined(_GCC) // GCC #define EXPORT __attribute__((visibility("default"))) #define IMPORT #else // do nothing and hope for the best at link time #define EXPORT #define IMPORT #endif #ifdef _CORE_COMPILATION #define PUBLIC_CORE EXPORT #define EXTERNAL_CORE #else #define PUBLIC_CORE IMPORT #define EXTERNAL_CORE extern #endif #include <deque> // force exporting of templates EXTERNAL_CORE template class PUBLIC_CORE std::allocator<int>; EXTERNAL_CORE template class PUBLIC_CORE std::deque<int, std::allocator<int> >; class PUBLIC_CORE MyObject { private: std::deque<int> m_deque; }; 

SO, my problem is that when I compile in Visual Studio (both in 2008 and 2010), I get the following warning:

warning C4251: 'Stand :: _ Deque_val <_Ty, _Alloc> :: _ ALMap': class' std :: allocator <_Ty> 'must have a dll interface to be used by clients of the class' Stand :: _ Deque_val <_Ty, _Alloc> '

It looks like I did not export the std::allocator<int> that I have. And it’s not like my export is wrong, because it does not include

 EXTERNAL_CORE template class PUBLIC_CORE std::allocator<int>; EXTERNAL_CORE template class PUBLIC_CORE std::deque<int, std::allocator<int> >; 

displays a warning:

warning C4251: "MyObject :: m_deque": class 'std :: deque <_Ty>' must have a dll interface that will be used by clients of class 'MyObject'

The only thing I can think of is that the _Ty warning about std::allocator says that it is somehow not int , but I cannot find any indication that it would be otherwise, since a std::deque<int> logically allocates using std::allocator<int> .

A consuming application may use the class just fine, but I have a feeling that this warning should not be ignored. When compiling with g ++ on Linux, they do not emit errors (although this does not mean that they work correctly). Does g ++ automatically do what MSVC cannot do? I aimed at GCC on Linux, LLVM on OSX, and MSVC on Windows, but I can potentially move on to developing MinGW for Windows, so abandoning MSVC is not entirely accurate (if this proves too much inconvenience).

+6
c ++ dll visual-c ++ templates
source share
1 answer

As you know, the templates in your export file are actually “permission to populate what you think is necessary” for the compiler.

This means that if you compile your header file with compiler A, it can create a completely different deque<int> than compiler B. The order of some members can change one or even the actual type of some member variables.

And this is what the compiler warns about.

EDIT: Adds Some Consequences to Explain

This way your shared libraries will work well together if they are compiled by the same compiler. If you want them to work together, you can either make sure that all client code "sees" the same declaration (using the same stl implementation), or backtrack on adding templates to your API.

+3
source share

All Articles