WINDOWS static library and dynamic library

A static library:

When compiling a static library, only .lib files will be generated . All data is in the lib file. There is only one way to use the static library, that is, static loading. During the program compilation and linking stage, all data in the static library will be linked and merged into the final generated exe file. After the link is completed, the static library file is no longer needed. This is convenient for program transplantation, but it also brings the disadvantage of excessive program bloat. At the same time, if the functions in the static library are changed, the project needs to be recompiled to generate a new exe file, which is more troublesome.

Two dynamic library:

When compiling a dynamic library, a .lib file and a .dll file will be generated . The lib file only contains the address information of the function or variable, and the specific implementation is in the dll file. The compilation and linking stage only needs the data in the .lib file, which has nothing to do with the dll file. The dll file will be used when the program is running, and has nothing to do with the lib file. The use of dynamic library includes static loading and dynamic loading. Static loading loads the dll file when the program starts, and dynamic loading uses the function LoadLibrary when needed and then manually loads the dll file. The time to load the dll file is even more. It is random and not all loaded together when the program starts. It is especially effective when a large number of dll files are used in the program. It reduces the time for program startup. It downloads specific dll files under specific conditions and disperses the loading time of dll files. At the same time, if the functions in the dynamic library have changed, you only need to replace the old dll file with the new dll file. The exe file does not need to be recompiled and generated, which is very suitable for occasions where the functions in the library need to be updated frequently.

Three solutions TestLibrary

The following is an explanation in conjunction with a specific project. The solution is TestLibrary, and the contents of the TestLibary directory are as follows:

Insert picture description here

The folder TestDll、TestLib、UseDll、UseLibis the main directory of the four projects, which are used to generate dynamic libraries , generate static libraries , use dynamic libraries , and use static libraries . The output file path of each project is set to Output.

1 Project TestLib

There are two files TestLib.hwith TestLib.cpp.

TestLib.hcontent:

// 注意:静态库导出函数无需使用extern "C" __declspec(dllexport)修饰

void TestLibFunc1();
void TestLibFunc2();

TestLib.cppcontent:

#include "TestLib.h"
#include <iostream>

void TestLibFunc1()
{
    
    
	std::cout << "TestLibFunc1" << std::endl;
}

void TestLibFunc2()
{
    
    
	std::cout << "TestLibFunc2" << std::endl;
}

Only TestLib.libfiles are generated after compilation .

2 Project TestDll

There are two files TestDll.hwith TestDll.cpp.

TestDll.hcontent:

// 注意:动态库导出函数一定要使用extern "C" __declspec(dllexport)修饰

// 如果不使用__declspec(dllexport)进行修饰,
// 编译时不会生成.lib文件。

// 如果不使用extern "C"进行修饰,会以C++的语法进行编译,
// 编译后的符号就不直接是原来的函数名而是会再加上了其他符号以支持C++的函数重载。

#define  extern "C" EXPORT __declspec(dllexport)

EXPORT void TestDllFunc1();
EXPORT void TestDllFunc2();

TestDll.cppcontent:

#include "TestDll.h"

#include <iostream>

void TestDllFunc1()
{
    
    
	std::cout << "TestDllFunc1" << std::endl;
}

void TestDllFunc2()
{
    
    
	std::cout << "TestDllFunc2" << std::endl;
}

Generate TestDll.liband TestDll.dllfile after compilation .

3 Project UseLib and UseDll

There is only one file main.cppused to call the functions in the library, and the specific content varies according to the loading method.

Four static loading and dynamic loading:

Static loading : load when the program starts.
Dynamic loading : load the library by calling library functions during the running of the program.

Five loading of static libraries

Because all the data in the static library is 编译链接阶段merged into all the programs exe文件, there is only one loading method for the static library.
Static loading includes two methods: configuration mode and code mode.

1 Static loading steps (configuration method)

  • Will be 头文件所在目录added to 附件包含目录. (Can be omitted)
  • Will be .lib文件所在目录added to 附加库目录.
  • Will be .lib文件名added to 附加依赖项.
  • In the code #include 头文件. (If step 1 is omitted, the path of the header file needs to be added at this time, and the relative path and absolute path are acceptable)

main.cppContent at this time :

#include "TestLib.h" 
// #include "..\\TestLib\\TestLib.h" 未设置附加包含目录时需要给出文件路径

int main()
{
    
    
	TestLibFunc1();
	TestLibFunc2();
	return 0;
}

2 Static loading steps (code method)

  • Add the directory where the header file is located to 附件包含目录. (Can be omitted)
  • Add the directory where the .lib file is located to 附加库目录. (Can be omitted)
  • In the code #include 头文件. (If step 1 is omitted, the path of the header file needs to be added at this time, and the relative path and absolute path are acceptable)
  • Use #pragma comment(lib, "lib文件名")load library. (If step 2 is omitted, you need to add the path of the lib file at this time, and the relative path and absolute path can be used)

main.cppContent at this time :

#include "TestLib.h" 
// #include "..\\TestLib\\TestLib.h" 未设置附加包含目录时需要给出文件路径

#pragma comment("lib", "TestLib.lib")
// pragma comment("lib", "..\\Output\\TestLib.lib") 未设置附加库目录时需要给出文件路径

int main()
{
    
    
	TestLibFunc1();
	TestLibFunc2();
	return 0;
}

Six dynamic library loading

The realization part of the dynamic library is in the .dll file, so the loading method of the dynamic library includes static loading and dynamic loading .

The static loading of the dynamic library is the same as the static loading of the static library . There is only one point to note: 需要将.dll文件放到.exe文件所在目录下,exe文件运行时只会在所在目录搜寻dll文件(动态载入也一样)**If it is not found, a system error message box will pop up:由于找不到***, 无法继续执行代码,重新安装程序可能会解决此问题。

Insert picture description here

The dynamic loading of the dynamic library is realized by calling related library functions in the code, including LoadLibrary(),, GetProcAddress()and so FreeLibrary()on. The dynamic loading method only needs to use the .dll file, and neither the header file nor the .lib file is required.

1 Dynamic loading steps

  • Call the LoadLibrary()load library and save the function return value for later GetProcessAddress()and FreeLibrary()use.
  • Call GetProcessAddress()the function required for searching, convert its return value into a function pointer, and use the function pointer to complete the function call.
  • Call the FreeLibrary()release library.

main.cppContent at this time :

#include "TestDll.h"
#include <windows.h>

typedef int(*FuncAddr)();

int main()
{
    
    
	HINSTANCE dllDemo = LoadLibraryA("..\\Output\\TestDll.dll"); // 必须给出文件所在路径
	if (dllDemo)
	{
    
    
		// 通过函数名称获取函数指针,需要注意,动态库的导出函数一定要使用extern "C"进行修饰
		// 否则这里通过函数名找不到对应函数
		
		FuncAddr func1 = (FuncAddr)GetProcAddress(dllDemo, "TestDllFunc1");
		if (func1 != nullptr) func1();
		FuncAddr func2 = (FuncAddr)GetProcAddress(dllDemo, "TestDllFunc2");
		if (func2 != nullptr) func2();
		
		FreeLibrary(dllDemo);
	}
	
	return 0;
}

Guess you like

Origin blog.csdn.net/xp178171640/article/details/112470852