The ability to create and use Templates is one of the great features of modern C++. The declaration of a template function or template class needs to be sufficiently flexible to allow it to be used in either a dynamic link library (shared library) or an executable file. In this article, we will explain how to export and import a template member function from a DLL or package in C++ with an example that can be used by a professional C++ Developer Tool.
Table of Contents
What is a template in C++?
A template is a very powerful statement in C++ which simply defines the operations of a class, a function, an alias or a variable and lets the user apply the same template on different data types in those template operations. Templates are similar to macros in C++ except the compiler checks the types used before the template is expanded.
How does a template in C++ work?
Here is an example of a function template that adds two a and b parameters of the T type:
1 2 3 4 5 6 7 |
template <class T> T add (T a, T b) { return a+b; } |
for example, if a and b are int variables, this template can be used as below:
1 2 3 |
int i = add <int> (a, b); |
and in the next lines same template can be used for the x and y float variables as below too,
1 2 3 |
float f = add <float> (x, y); |
Templates are very useful, and they are the base of generic programming that allows writing code in a way that is independent of any particular type. A template is an entity which generates an ordinary type or a function at compile time based on arguments the user supplies for the template parameters.
What are the steps to export and import template members from a DLL or a package in C++?
The declaration of a template function or template class needs to be sufficiently flexible to allow it to be used in either a dynamic link library (shared library) or an executable file. The same template declaration should be available as an import and/or export, or without a modifier. To be completely flexible, the header file template declarations should not use __export or __import modifiers. This allows the user to apply the appropriate modifier at the point of instantiation depending on how the instantiation is to be used.
The following steps demonstrate exporting and importing of templates. The source code is organized in three files. Using the header file, code is generated in the dynamic link library.
- Exportable/Importable Template Declarations
The header file contains all template class and template function declarations. An export/import version of the templates can be instantiated by defining the appropriate macro at compile time. - Compiling Exportable Templates
Write the source code for a dynamic link library. When compiled, this library has reusable export code for templates. - Using ImportTemplates
Now you can write a calling function that uses templates. This executable file is linked to the dynamic link library. Only objects that are not declared in the header file and which are instantiated in the main function cause the compiler to generate new code. Code for a newly instantiated object is written into main.obj file.
How to export and import template members from a DLL or a package in C++?
When you export a class that contains template member functions from a DLL or a package (using the __declspec(dllexport)
directive or the PACKAGE
macro, respectively), these members must be explicitly instantiated and exported. Otherwise, consumers of the exported class might run into unresolved external errors regarding the template member. For example we may have the following app invoking the bar member from a package and it may have an unresolved external error,
Here is a C++ app example (myapp.cpp
) that requires X template,
1 2 3 4 5 6 7 8 9 10 11 12 |
#include "mypackage.h" int g = 6; int main() { X x; x.foo(); return x.bar(&g); } |
In the above example when we try to invoke a method member, we may get an unresolved external as in the example below:
1 2 3 4 |
Error: Error: Unresolved external 'int X::bar<int>(int*)' referenced from C:\USERS\ADMIN_000\APPDATA\LOCAL\TEMP\MYAPP-233656.O |
To resolve the error, we should explicitly instantiate and export the member template used by our application. We should add the following line to C++ codes of this DLL or package.
1 2 3 |
template PACKAGE int X::bar<int>(int*); |
Is there a full example of how to export and import template members from a DLL or a package in C++?
If we continue to example above, we can explicitly instantiate and export the member template foo().
Here is a simple C++ package or DLL example (mypackage.cpp
),
1 2 3 4 5 6 7 8 9 |
#include "mypackage.h" int X::foo() { return 7; } template PACKAGE int X::bar<int>(int*); // explicitly instantiate and export the member template |
and here is a header example (mypackage.h
) for the C++ package or DLL example above.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#define PACKAGE __declspec(package) class PACKAGE X { public: int foo(); template<typename T> int bar(T *p) { return *p; } }; |
Both the .cpp
and .h
example above resides in a C++ package.
Then you can safely run your application. Here is a C++ app example (myapp.cpp
) that requires the X template from this package:
1 2 3 4 5 6 7 8 9 10 11 12 |
#include "mypackage.h" int g = 6; int main() { X x; x.foo(); return x.bar(&g); } |
If you need more details about Class Templates you can check this official docwiki
C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.
There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise versions of C++ Builder and there is a trial version you can download from here
Design. Code. Compile. Deploy.
Start Free Trial
Free C++Builder Community Edition