Windows DLL的生成与使用

DLL基础部分

    通过对函数前加前缀:__declspec(dllexport) 或__declspec(dllimport),表明函数或类是导出到DLL,还是从DLL中导入。但在C++中,通过编译会改变函数名称,可以通过如下的宏进行更正,但过程比较繁琐,不适用于大批量改变函数名称的情况。

#pragma comment(linker, "export:Myfun=MyFun@8"

为了解决这个问题,可以通过另外的两种办法:

  1. 添加 extern "C"标识,如下文代码示例所示。
  2. 在.def文件中进行定义
 void extern "C" __declspec(dllexport) funcName()
{
    // Your code here
}

 


1. 相对虚拟地址

编译后生成的DLL,将函数放在了各自相对应的偏移地址上,包括变量等信息的地址。

2. 构建可执行模块

通过Dumpbin程序,可以查看到函数的导入情况:dumpbin -imports calc.exe

3. 运行可执行模块

需要运行可执行模块,需要查看模块所需要的DLL,但又是按照什么规则进行查找和加载的呢?规则如下:

  1. 可执行文件目录
  2. Windows系统目录——GetSystemDirectory可以获得
  3. Windows目录——GetWindowDirectory可以获得
  4. 进程当前目录(防止伪造的Windows DLL,故在windows目录后)
  5. PATH环境变量中的目录

这个只是微软预先配置好的搜索路径,若需要按照自定义的,需要修改注册表中对应的内容。


DLL载入

DLL载入方式有两种,一种是隐式,另一种为显式。

隐式:

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

显式:

    有以下两个函数LoadLibrary和LoadLibraryEx。其中带Ex可以附带属性控制,大致有如下几个功能:

1DONT_RESOLVE_DLL_REFERRENCES

1. 不适用DllMain初始化

2. 不载入依赖

2LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVEDLL是否独占方式打开
3LOAD_LIVRARY_AS_DATAFILE是否按照资源文件导入
4LOAD_WITH_ALTERED_SEARCH_PATH自定义DLL搜索路径等
5LOAD_LIBRARY_AS_IMAGE_RESOURCE虚拟地址修复

更详细的介绍可以见此地址

HMODULE LoadLibraryA(
  LPCSTR lpLibFileName
);

HMODULE LoadLibraryExA(
  LPCSTR lpLibFileName,
  HANDLE hFile,
  DWORD  dwFlags
);

显式载入后,通过获得的HMOUDLE句柄,可以显示链接到需要导出的符号,需要定义一个相对应的函数指针进行转换:

FARPROC GetProcAddress(
  HMODULE hModule,
  LPCSTR  lpProcName
);

DLL释放

载入的DLL资源的回收:

BOOL FreeLibrary(
  HMODULE hLibModule
);

小结:

通过DLL的方式,可以很方便的进行开发工作,将功能相近的封装到一起,在一定程度上可以方便软件规模的管理。同时,DLL加载方式决定了软件启动速度,通过只初始化必要的组件,来加快启动,并在后期需要调用一些功能的时候再进行选择性的加载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值