I have a dll that contains a templated class. Is there a way to export it 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.
Are you looking into exporting an instantiation of a template class through a dll? A class along the lines:
typedef std::vector<int> IntVec;
There is some discussion how to do this on:
http://support.microsoft.com/kb/168958
Another approach is to explicitly exporting each function you are interested in through a wrapper class working against this template instance. Then you won't clutter the dll with more symbols than you are actually interested in using.
When the compiler finds an instantiation of a template class, like MyTemplate<int>, then it generates the code for the template specialization.
For this reason, all the template code must be placed in an header file and included where you want to use it.
If you want to 'export' your template class, just place your code in an header file and include it where it's needed.
In your export control file.
#ifdef XXXX_BUILD
#define XXXX_EXPORT __declspec(dllexport)
#define XXXX_EXTERN
#else
#define XXXX_EXPORT __declspec(dllimport)
#define XXXX_EXTERN extern
#endif
where XXXX_BUILD is a symbol defined in your project.
To get your class exported.
XXXX_EXTERN template class XXXX_EXPORT YourClass<double>;
Where double is the type you want to instantiate the class with.
https://support.microsoft.com/en-us/help/168958/how-to-export-an-instantiation-of-a-standard-template-library-stl-clas
Related
I have a dll that contains a templated class. Is there a way to export it 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.
Are you looking into exporting an instantiation of a template class through a dll? A class along the lines:
typedef std::vector<int> IntVec;
There is some discussion how to do this on:
http://support.microsoft.com/kb/168958
Another approach is to explicitly exporting each function you are interested in through a wrapper class working against this template instance. Then you won't clutter the dll with more symbols than you are actually interested in using.
When the compiler finds an instantiation of a template class, like MyTemplate<int>, then it generates the code for the template specialization.
For this reason, all the template code must be placed in an header file and included where you want to use it.
If you want to 'export' your template class, just place your code in an header file and include it where it's needed.
In your export control file.
#ifdef XXXX_BUILD
#define XXXX_EXPORT __declspec(dllexport)
#define XXXX_EXTERN
#else
#define XXXX_EXPORT __declspec(dllimport)
#define XXXX_EXTERN extern
#endif
where XXXX_BUILD is a symbol defined in your project.
To get your class exported.
XXXX_EXTERN template class XXXX_EXPORT YourClass<double>;
Where double is the type you want to instantiate the class with.
https://support.microsoft.com/en-us/help/168958/how-to-export-an-instantiation-of-a-standard-template-library-stl-clas
I'm attempting to build a static library, containing definitions of DDS topics obtained from various IDL files. I'm using OpenDDS as my middleware.
When I create an IDL file containing a sequence<long>, compile it into my static library, and then link the static library against my application, I get linker errors involving multiple definition of symbols:
Error LNK2005 "public: void __cdecl TAO::unbounded_value_sequence<int>::length(unsigned int)" (?length#?$unbounded_value_sequence#H#TAO##QEAAXI#Z) already defined in TAO.lib(TAO.dll)
I believe this is because my static library contains a template instantiation of unbounded_value_sequence, and my application also contains an instantiation. It seems to be coming from within ACE TAO, which is used by OpenDDS.
I'm looking for a way to avoid instantiating the template in my static library altogether, so that it can just use the definition within the application when they are linked together. I tried adding the following:
extern template class TAO::unbounded_value_sequence<int>;
This produced the following error:
Error C2961 'TAO::unbounded_value_sequence<CORBA::Long>': inconsistent explicit instantiations, a previous explicit instantiation did not specify '__declspec(dllimport)'
I've tried to locate that instantiation, but its not in my code. It may be within ACE itself.
The problem does not occur if I build everything in the one project, but that is not an ideal solution.
What you have to do to use extern templates is a bit different. Indeed, declaring the extern template will prevent it's instanciation. But you will need an instanciation somewhere. That somewhere is usually in a cpp with the name of the template you want to compile.
unbounded_value_sequence.h:
// template struct here
extern template class TAO::unbounded_value_sequence<int>;
extern template class TAO::unbounded_value_sequence<long>;
// and every other instantiation you want to be in your static library
unbounded_value_sequence.cpp:
#include "unbounded_value_sequence.h"
// Here you compile them one time.
template class TAO::unbounded_value_sequence<int>;
template class TAO::unbounded_value_sequence<long>;
// and every other instantiation you want to be in your static library
That will make your template to be instantiated one time only, inside your library. The compiler will generate a unbounded_value_sequence object file that contains your template instantiations. They will exist only there.
Don't forget that you still need to make your template implementation visible in the header if you want users of your library use your template class with theirs.
I have a C++ class library project that is commonly used by other C++ projects. To be able to use classes inside my class library project, I wrote a header file like the example given below
#pragma once
#ifdef MYLIB
# define MYLIB_EXPORT __declspec(dllexport)
#else
# define MYLIB_EXPORT __declspec(dllimport)
#endif
No problem until I want to create a template class inside my class library project. The problem is I can't export my template class.
MyClass.h
template<class T>
class MYLIB_EXPORT MyClass
{
void myMethod();
// ...
}
template<class T>
void MyClass::myMethod()
{
// ...
}
In this case I am getting compilaton errors saying "definition of dllimport function not allowed". I know what causes the problem and I understand it. Other projects using my class library project converts the MYLIB_EXPORT keyword to __declspec(dllimport). Therefore, they are expecting the methods of MyClass to be defined in a DLL. But, then the compiler sees the definition inside the header.
How can I overcome this situation and be able to export my template classes that are defined inside my class library project?
Uninstantiated templates can't be compiled directly - they are code generators, so they are actually translated to binary instructions only when they are instantiated; for this reason, you can't export a template "in binary form" as if it was a "regular" function/class (on the other hand, at least in theory you could export an instantiation of a template).
Long story short: just leave the templates in a header to be included by library clients.
Notice that this is the exact reason why you keep templates in headers and you don't normally separate their implementation in .cpp files.
Just remove the MYLIB_EXPORT statement on template class. Then you can define class functions outside the class (but still in *.h or *.hpp header files).
MyClass.h
template <typename T>
class MyClass // MYLIB_EXPORT removed
{
void myMethod();
// ...
};
template <typename T>
void MyClass<T>::myMethod()
{
// ...
}
I got this issue. After a long time, I realized removing MYLIB_EXPORT fixed it. Hope this answer will save time to others :-)
I'm trying to understand some C++ code which has the following class syntax:
class Q_MONKEY_EXPORT BasePlugin : public QObject
{
// some code comes here
};
I cannot understand the syntax class Q_MONKEY_EXPORT BasePlugin. To me it looks like if there are two names for the class. What exactly does this kind of syntax mean in C++?
Q_MONKEY_EXPORT is most likely a #define somewhere. Defines like that are sometimes required, for example when the class is in a library and needs to be exported when the header file is included from somewhere else. In that case, the define resolves to something like __declspec(dllexport) (the exact syntax will depend on the tools you are using).
That's most probably a preprocessor directive telling the compiler the symbol is to be exported.
It's probably defined as:
#define Q_MONKEY_EXPORT _declspec(dllexport)
which will cause your class to be exported to the dll.
The full declaration will be expanded, before compilation, to:
class _declspec(dllimport) BasePlugin : public QObject
{
// some code comes here
};
EDIT:
As David Heffernan pointed out, macros like these are generally used to let the compiler know whether it needs to import or export the symbols. Usually defined as dllimport for outside modules and dllexport when building the module. I doubt that's the case here, since the name suggests exporting, but it's best to check the documentation or actually go to the definition.
Q_MONKEY_EXPORT is a macro (all upper case is convention for macro) that typically resolves to something like __declspec(dllexport) when you are building the DLL and resolves to __declspec(dllimport) when you are using the DLL.
You can find out exactly what it is by reading your include files.
I have a dll that contains a templated class. Is there a way to export it 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.
Are you looking into exporting an instantiation of a template class through a dll? A class along the lines:
typedef std::vector<int> IntVec;
There is some discussion how to do this on:
http://support.microsoft.com/kb/168958
Another approach is to explicitly exporting each function you are interested in through a wrapper class working against this template instance. Then you won't clutter the dll with more symbols than you are actually interested in using.
When the compiler finds an instantiation of a template class, like MyTemplate<int>, then it generates the code for the template specialization.
For this reason, all the template code must be placed in an header file and included where you want to use it.
If you want to 'export' your template class, just place your code in an header file and include it where it's needed.
In your export control file.
#ifdef XXXX_BUILD
#define XXXX_EXPORT __declspec(dllexport)
#define XXXX_EXTERN
#else
#define XXXX_EXPORT __declspec(dllimport)
#define XXXX_EXTERN extern
#endif
where XXXX_BUILD is a symbol defined in your project.
To get your class exported.
XXXX_EXTERN template class XXXX_EXPORT YourClass<double>;
Where double is the type you want to instantiate the class with.
https://support.microsoft.com/en-us/help/168958/how-to-export-an-instantiation-of-a-standard-template-library-stl-clas