How to Export Templated Classes from a Dll Without Explicit Specification

How do I export templated classes from a dll without explicit specification?

Since the code for templates is usually in headers, you don't need to export the functions at all. That is, the library that is using the dll can instantiate the template.

This is the only way to give users the freedom to use any type with the template, but in a sense it's working against the way dlls are supposed to work.

How to instantiate the template in C++

Yes, it called explicit instantiation See 14.7.2 of the C++11 standard (sorry I have no C++03 nearby).

You may instantiate in your translation unit as much as you wish instances of your template w/ any types you want, and this code will be placed into your DLL. And everything else just wouldn't.

Storing C++ template function definitions in a .CPP file

The problem you describe can be solved by defining the template in the header, or via the approach you describe above.

I recommend reading the following points from the C++ FAQ Lite:

  • Why can’t I separate the definition of my templates class from its declaration and put it inside a .cpp file?
  • How can I avoid linker errors with my template functions?
  • How does the C++ keyword export help with template linker errors?

They go into a lot of detail about these (and other) template issues.

C++ template specialization in different dll produces linker errors

I know you said that you dont want to modify the header since it could break the third party library updates, but the header that the template is defined in is not set up correctly. Hopefully you can get your vendor to modify their headers to be more import/export friendly.

The goal:

Define (export) a template specialization in a dll/so and then use (import) that specialization to your exe.

test.h


We dont want to only import or export every specialization of the template, so we remove the LIB_EXPORT from the class.

template <typename A> class Foobar {
...
}

We do want to import/export a specific specialization of the template however. We will forward declare the specialization and then explicitly instantiate it later in the compilation unit you want it to reside in.

Since you are also building with gcc, you will want to make use of the 'extern' keyword. Visual Studio 2010 does not implement it for templates.

#ifdef _WIN32
# define TEMPLATE_EXTERN
#ifdef EXPORT
# define LIB_EXPORT __declspec(dllexport)
#else
# define LIB_EXPORT __declspec(dllimport)
#endif
#else
# define TEMPLATE_EXTERN extern
# define LIB_EXPORT
#endif

The final forward declaration looks like

TEMPLATE_EXTERN template class LIB_EXPORT Foobar<int>;

test.cpp


We explicitly instantiate the template class here since our efforts in the header file have turned off the automatic instantiation features of the compiler.

#define EXPORT
#include "test.h"

template class Foobar<int>;

main.cpp


The default state of the headers is to implicitly instantiate the Foobar class with any type that is not int. The int specialization has been specifically tagged as 'export' on gcc and __declspec(dllimport) on win32. So you are able to make other specializations wherever you wish.

#include "test.h"

// explicit instantiation
template class Foobar<char>;

int main(int argc, char** argv)
{
Foobar<char> a;
a.helloWorld();
}


Related Topics



Leave a reply



Submit