动态链接库基础-隐式链接与显式链接

来源:互联网 发布:天蝎座为什么被黑 知乎 编辑:程序博客网 时间:2024/06/01 19:48

静态链接库(*.lib)

如果在程序中使用静态链接库,那么编译器在链接的过程中会将*.obj文件和*.lib文件组织成可执行exe文件,也就是将.lib中的代码链接到可执行文件中,因此生成的exe文件比较大。程序运行时会将其所需数据一次性全部加载到内存,其缺点也比较明显:加载时间比较长。程序在发行时不需要提供库文件。

动态链接库(*.dll)

动态链接库又分为两种加载方式:隐式加载和显式加载。

隐式加载是程序载入内存时加载所需的dll文件,且该dll随主进程始终占用内存。在编码时需要使用#pragma comment(lib,"myDll.lib")获得所需函数的入口。注意该.lib与静态链接库的.lib文件不同,静态链接库的.lib中包含了所需函数的代码,动态链接库的.lib仅指示函数在dll文件中的入口。

显式加载是在程序运行过程中加载,不需要该dll时则将其释放。在需要时使用LoadLibrary加载,不需要时使用FreeLibrary释放。如果在LoadLibrary时该dll已经在内存,则只需将其引用计数加1,如果其引用计数减为0则移出内存。

使用动态链接库的程序在发行时需要提供dll文件。

在编译时,如果使用隐式链接则需要提供.lib文件,生成可执行文件后则不再需要该.lib。如果使用显式链接,在编译时不需提供.lib文件。

下面给出一个动态链接库的小Demo

dll源码:

#include <Windows.h>  #include <stdio.h>  extern "C" {_declspec(dllexport) int testAdd(int x, int y){return x + y;}}

使用隐式链接的主函数:

#include"stdafx.h"using namespace std;#pragma comment(lib,"myDll.lib")extern "C" {_declspec(dllimport) int testAdd(int x, int y);}int   main(int   argc, TCHAR  *argv[]) {_tprintf(_T("sum is %d\n"), testAdd(2,5));system("pause");return 0;}

使用显式链接的主函数:

#include"stdafx.h"using namespace std;int   main(int   argc, TCHAR  *argv[]) {HINSTANCE h = LoadLibrary(_T("myDLL"));GetErrorMessage(GetLastError(), 0);int(*pAdd)(int, int) = NULL;pAdd = (int(__cdecl *)(int, int))(GetProcAddress(h, "testAdd"));GetErrorMessage(GetLastError(), 0);if (pAdd == NULL) {FreeLibrary(h);return 0;}int sum = pAdd(239, 23);_tprintf(_T("sum is %d\n"), sum);FreeLibrary(h);system("pause");return 0;}


原创粉丝点击