Dll

dllexport(导出)

当 Microsoft 的C/C++编译器看到_declspec(dllexport)修饰符修饰的变量、函数原型或 C++类的时候,会在生成的.obj文件中嵌入一些额外的信息。

当链接器在链接 DLL 所有的.obj文件时,会解析这些信息。
在链接 DLL 的时候,链接器会检测到这些与导出的变量、函数或类有关的嵌入信息,并生成一个.lib 文件。

这个.lib 文件列出了该 DLL 导出的符号,在链接dll导入函数和变量的时候,只要引用了该 DLL 导出的符号,这个.lib 文件是必需的。

除了创建这个.lib 文件之外,链接器还会在生成的 DLL 文件中嵌入一个导出符号表。这个(按字母顺序排列的)导出段列出了导出的变量、函数和类的符号名。链接器还会保存相对虚拟地址(RVA),表示每个符号可以在 DLL模块中的何处找到。

DumpBin.exe(加上-exports)可以查看一个dll的导出段。

 使用

#ifdef SYSTEM_EXPORTS
#define SYSTEM_API __declspec(dllexport) 
#else 
#define SYSTEM_API __declspec(dllimport) 
#endif

class SYSTEM_API MSystem
{
	public:
		static TCHAR ms_sLogBuffer[LOG_BUFFER_SIZE];
		static DWORD ms_dwMainThreadID;
};

构建dll和构建EXE

头文件:其中包含待导出函数的原型结构和符号的声明结构和符号的声明

源文件:其中包含待导出函数实现和变量的实现和变量

编译器:为每个C/C++源文件生成.obj文件

构建dll:

连接器:链接器将每个.obj模块合并,从而生成DLL,如果至少导出了一个函数/变量,那么链接器会同时生成.lib文件

构建EXE

链接器将每个.obj模块合并,并使用.lib文件来解析对导入的函数/变量的引用,从而生成.exe(它包含一个导入表,其中列出了必需的DLL和导入的符号)

dll隐式载入

直接在脚本中使用__declspec(dllimport)修饰要导入的方法。

dll显式载入

//游戏引擎debug模式内存申请
#include <DbgHelp.h>
typedef BOOL
(WINAPI
	* tFSymGetLineFromAddr64)
	(
		IN  HANDLE                  hProcess,
		IN  DWORD64                 qwAddr,
		OUT PDWORD                  pdwDisplacement,
		OUT PIMAGEHLP_LINE64        Line64
		);

static tFSymGetLineFromAddr64 fnSymGetLineFromAddr64 = NULL;
static HMODULE s_DbgHelpLib = NULL;

// 查找当前目录的DLL 获取文件映像被映射到调用进程的虚拟地址
s_DbgHelpLib = LoadLibrary(szDbgName);

//根据名称获取函数的地址
fnSymGetLineFromAddr64 = (tFSymGetLineFromAddr64)GetProcAddress(s_DbgHelpLib, "SymGetLineFromAddr64");

dll显式卸载

if (s_DbgHelpLib != NULL)
{
		FreeLibrary(s_DbgHelpLib);
		s_DbgHelpLib = NULL;
}

dll的写时复制

 //TODO

函数转发器

这个 pragma 告诉链接器,正在编译的 DLL 应该输出一个名为 SomeFunc 的函数,但实际实现 SomeFunc 的是另一个名为 SomeOtherFunc 的函数,该函数被包含在另一个名为DIlWork.dl的模块中。我们须为每个想要转发的函数单独创建一行 pragma。

#pragma comment(linker."/export:SomeFunc=D11Work.SomeOtherFunc")

dll延时载入

 //TODO

dll重定向

 特性:

强制操作系统的加载程序首先从应用程序的目录中载入模块,只有当华仔程序无法找到要找的文件时,才会在其他目录中搜索。我们需要把一个名称为AppName.local(AppName替换项目exe的名称)的文件放到应用程序的目录中。

基地址重定向

 

dll搜索顺序

1.包含可执行文件的目录。

2.Windows 的系统目录,该目录可以通过 GetSystemDirectory 得到

3.16位的系统目录,即Windows 目录中的System 子目录。

4.Windows目录,该目录可以通过 GetWindowsDirectory 得到。

5.进程的当前目录。

6.PATH 环境变量中所列出的目录

 

隐式载入太多dll会加长程序的初始化时间。

posted @ 2023-02-07 15:26  过往云烟吧  阅读(314)  评论(0)    收藏  举报