Use templates in both dynamic and static libraries (dynamic libraries static libraries)

  • 2020-06-01 10:23:26
  • OfStack

Dynamic import libraries and static libraries: they are essentially different things. The static library itself contains the actual execution code, symbol table, etc., while for the import library, the actual execution code is located in the dynamic library, and the import library only contains the address symbol table, etc., ensuring that the program finds some basic address information of the corresponding function

Problem analysis: template functions and template classes are difficult to use in the library, but not impossible, because only the template function with the corresponding parameter type has an instance inside the library to successfully export the template function. There must be instances of all public member functions (including constructs/destructors) of the template class.

Why you instantiate templates: only if you instantiate the template functions or template classes in the export library can you save the address information of the template functions and template class instantiated after instantiation in the export library.

Demonstration: let me give you an example of a dynamic library (dynamic libraries).


//<span style="font-family:'Microsoft YaHei';">TemplateLib.h</span><span style="font-family:'Microsoft YaHei';"> Using a dynamic library </span>
#ifdefTEST_DLL_EXPORTS
#define TEST_API__declspec(dllexport)
#else
#define TEST_API__declspec(dllimport)
#endif
//  Derived template function 
template<typename T1>
TEST_APIvoidfun1(T1);

template<typename T1,typename T2>
TEST_APIvoidfun2(T1 , T2);
//  Template class 
template<typename T,int size>
class TEST_APICTest
{
public:
CTest() {};
~CTest(){};
T*GetDataBuff() { return m_data;}
private:
T m_data[size];
};

// TemplateLib.cpp :  define  DLL  The export function of the application. 
#include "stdafx.h"
#include "TemplateLib.h"
// 1. The use of overloading to instantiate different types of templates, the amount of code does not say, is basically repetitive code 
// 2. The library designer doesn't know what type the user is going to pass in, so the designer can't instantiate everything 1 Types of templates. 
TEST_APIvoid fun1(int var1) {}
TEST_APIvoid fun1(char var1){}
template<typename T1,typename T2>
TEST_APIvoid fun2( T1 var1, T2 var2){}
//  This namespace is not used as an export, only 1 Functions are used to instantiate function and class templates .
namespace implement_template_private
{
voidimplement_template()
{
int idata = 10;
charchr = 'x';
float fdata = 20.f;
UINTundata= 9;
char* str = "hello";
//  This way of instantiating, the amount of code is much less than the load method, but it needs to be run 1 Sub the template function 
//  It may be unreasonable at some point to run this function out of thin air. 
fun2(idata,chr);// int,char
fun2(undata,str); // UINT,char*
fun2<float,char*>(fdata,str); // float,char*  Display parameters 
//  Instantiation of the export class. 
// 1. In addition to instantiating the public member functions that are provided to the user, there are also implicit instantiations of constructors and destructors .
// 2. Notice how each of these 1 The instantiation of each template is unique 1 . 
// 3. If the customer USES it in the project CTest<char,30> impl_obj;  There will be a connection error,   The template's parameter list must match exactly. 
// 4. If the template class is very large and has a lot of functionality, then the instantiation effort is, as you can imagine, unbearable. 
// 5. The library designer doesn't know what type the user is going to pass in, so the designer can't instantiate everything 1 Types of templates. 
CTest<char,20>impl_obj;
impl_obj.GetDataBuff();
CTest<int,5>impl_obj2;
impl_obj.GetDataBuff();
}
};
//

Use the dynamic library we just created for another project


// TemplateExport.cpp :  Define the entry point for the console application. 
//
#include "stdafx.h"
#include "..\TemplateLib\TemplateLib.h"
#pragma comment(lib,"TemplateLib.lib")

int _tmain(int argc, _TCHAR* argv[])
{
fun1<int>(10);
fun1<char>('x');
//fun1<float>(20.f);//  Connection error 
fun2<float,char*>(20,"hello");
//fun2<int,int>(20,30); //  Connection error 
CTest<char,20> test;
char* ret = test.GetDataBuff();
//CTest<char,30> test2; //  Connection error 
return 0;
}

Summary and advice: it is not recommended to use template-related techniques in an export library. If you can determine what types (type) will be passed in when users use your template functions, the designer should instantiate these types of template-1 1.

That's all you need to know about using templates in both dynamic and static libraries.


Related articles: