Windows编程之动态链接库

动态链接库

动态链接库就是大家俗称的DLL文件,在windows系统中非常常见,是一个可以被其他程序共享的功能模块。动态连接库是不能直接执行的,它只能作为导出函数,被其他exe文件调用,一般我们都会说“导入/加载动态链接库”。

导出函数

刚才说到了一个导出函数的概念,导出函数一般跟内部函数进行比较,内部函数就是在这个文件中内部定义的函数,只能这个文件来调用。而导出函数是在这个文件中定义,这个文件能够使用,但是别的文件也是同样可以使用的。

动态链接库编程

动态链接库,顾名思义,是当程序执行的时候需要用到一些导出函数的时候才加载DLL文件,并且在使用之后会卸载掉,意味着可以节省内存。

在我们进行动态链接库编程的时候,首先需要编写DLL文件,可以用IDE新建一个动态链接库的项目,会自动生成一个DLLMain.cpp文件,里面有定义好的模版。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

其中DLL_PROCESS_ATTACH是加载到内存的时候执行,DLL_THREAD_ATTACH是进程中有线程时执行,DLL_THREAD_DETACH是进程中线程被结束的时候执行,DLL_PROCESS_DETACH是从内存中卸载的时候执行。

我们想要定义自己的导出函数的话,就在main函数的上面或者下面都可以

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "stdafx.h"

int MyMessageBox(char* lpText, char* lpCaption) {
MessageBoxA(NULL, lpText, lpCaption, 0);
return 0;
}

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

写好了定义的代码,我们还需要新建一个模版定义文件,是.def后缀的文件,其中声明要导出的函数名称

1
2
EXPORTS
MyMessageBox

然后我们进行编译,就会得到dll文件了。

之后我们新建一个.c文件,定义main函数,来加载我们编译好的动态链接库文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <windows.h>


typedef int(*MyMessageBox)(char* lpText, char* lpCaption);


int main(int argc, char* argv[]) {
HMODULE hModule = LoadLibrary("DLLP.dll");
if (hModule == NULL) {
printf("LoadLibrary error\n");
return 0;
}
MyMessageBox NewMessageBox = (MyMessageBox)GetProcAddress(hModule, "MyMessageBox");
if (NewMessageBox == NULL) {
printf("GetProcAddress error\n");
return 0;
}
NewMessageBox("Hello, my friend.", "Pino_HD");
FreeLibrary(hModule);
return 0;
}

代码中我们必须要先定义好我们需要引用的函数原型,在main函数中,使用LoadLibrary函数加载DLL文件,该函数会返回一个DLL文件的句柄,然后使用GetProcAddress获取导出函数的地址,其参数是之前返回的句柄,以及导出函数的名称。最后调用导出函数即可。当然了,最后不要忘记用FreeLibrary函数将句柄清空。

1
gcc dllp.c -o dllp

编译之后执行可执行文件即可发现有弹窗。

本文标题:Windows编程之动态链接库

文章作者:Pino-HD

发布时间:2018年09月30日 - 14:09

最后更新:2018年09月30日 - 15:09

原始链接:https://pino-hd.github.io/2018/09/30/Windows编程之动态链接库/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

坚持原创技术分享,您的支持将鼓励我继续创作!