Windows开发之动态库加载

前段时间写代码,主进程要加载很多dll,刚开始写的dll动态加载,好麻烦的说。老大说写成静态加载,理解错了意思,改成了静态库,真的傻。好长时间没写动态库,忘得差不多了,笔记里也是简单记了下。最后改成了个dll静态加载,现在来总结一下吧。

动态库,在Windows下为dll文件,Linux下是so,这里先不讨论。dll文件即可执行文件的一种,也是就PE文件,还有一种常见的PE文件格式就是exe文件,也就是Windows程序。动态库不能单独执行,必须加载到某一进程中,动态库的加载可分为静态加载和动态加载。在程序里加载动态库叫加载,向其他程序加载动态库就叫注入了,这个后边再写。

1.动态加载

动态加载也是运行时加载,是在程序运行到加载语句的时候才会加载动态库,动态加载调用api接口LoadLibrary。

HMODULE LoadLibraryA(
  LPCSTR lpLibFileName
);

接口返回动态库句柄,接着调用GetProcAddress,获得导出函数地址,加载动态库的目的就是调用动态库中的接口。

FARPROC GetProcAddress(
  HMODULE hModule,
  LPCSTR  lpProcName
);

返回函数地址,再次之前要使用typedef定义函数类型,为指向导出函数的指针。函数返回值和形参和导出函数相同。接着就可以用调用定义的函数方式调用导出函数。

最后使用FreeLibrary释放模块句柄。

BOOL FreeLibrary(
  HMODULE hLibModule
);

在动态库中要在要导出的函数前面加

extern "C"
_declspec(dllexport)

动态加载的另一种方式是def文件,这个还没见过,以后再补充吧。上述的动态加载过程只需要提供dll文件。

2.静态加载

扫描二维码关注公众号,回复: 4635911 查看本文章

静态加载是在函数的编译时候就将模块代码加载到程序中。静态加载也有两种方式,一种是def文件,另一种是_declspec(dllexport)

1)def文件

def文件的格式如下:

LIBRARY MoudleName
EXPORTS 
    Function1 @1
    Function2 @2
    ...

在使用时在文件头加上下面这句,需要提供包括生成的.lib和.dll文件,编译时不需要头文件,提供头文件可以告诉别人调用那些接口

#pragma comment(lib,"DllName.lib")

在动态库的函数中需要加上WINAPI调用约定,这是我遇到的问题,没有调用约定会不认识。 

2)_declspec(dllexport)

在动态库的导出函数前加

extern "C"
_declspec(dllexport)

使用时在文件前面加上

#include "DllName.h"

#pragma comment(lib,"DllName.lib")

extern "C"
_declspec(dllexport) Function()

这种加载方式需要提供头文件、lib文件和dll文件。

lib文件为动态库的导入库,提供给程序函数地址符号等,并不是静态库。

猜你喜欢

转载自www.cnblogs.com/w1ng/p/10171582.html
今日推荐