首页 > 其他分享 >Dll

Dll

时间:2023-02-07 15:35:26浏览次数:35  
标签:文件 函数 导出 dll DLL 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会加长程序的初始化时间。

标签:文件,函数,导出,dll,DLL,Dll,链接
From: https://www.cnblogs.com/zjr0/p/17088377.html

相关文章

  • 8.6DLL文件及导入库
    Windows以函数的形式为应用提供了各种功能。这些形式的函数称为API(应用程序接口)。例如,Samplel.c中调用的MessageBox0,它并不是C语言的标准函数,而是Windows提供的API的一......
  • playwright 运行报错ImportError: DLL load failed
    使用playwright编写了一个爬虫程序,放到远程的windowsserver服务器上面运行的时候出现下面错误File"<frozenimportlib._bootstrap>",line1206,in_gcd_importFil......
  • 缺少 vcruntime140_1.dll
    情景:安装mysql解压包提示缺少 vcruntime140_1.dll下载vcruntime140_1.dll,将下载过来的dll文件复制到C:\Windows\System32目录下(windows64位系统)  成功install后,启动m......
  • .net core build 工具无法引用COM DLL 则可以使用nuget包
    我使用命令行构建项目,提示无法引用COMDLL需要使用.NETfromwork版的构建工具其实可以通过nuget包来导入其他人创建的COMDLL包装程序集,这样就可以使用.NETcore的构......
  • Matlab编译生成DLL,供QT调用
    QT5.15.2MatlabR2022a一、使用matlab生成dll准备好matlab接口命令行窗口敲入以下命令:  弹出以下对话框 选择LibraryCompiler弹出以下对话框  选择C......
  • 【悲伤的Debug日志】Windows Anaconda 运行报错 ImportError: DLL load failed while
    今天在Windows10上安装Anaconda(Anaconda|AnacondaDistribution)。首次安装选择了“在所有用户上安装”,发现进入下一步时无法勾选“将Anaconda加入PATH环境变......
  • C#调用C++动态链接库dll之P/Invoke方式 — 2.在C#控制台程序中调试C++动态链接库
    很简单1.C#控制台项目右键-属性-生成-允许不安全代码-打勾;2.C#控制台项目右键-属性-调试-启用本地代码调试-打勾;......
  • C#未能添加“dll”的引用
      遇到此问题,原因及解决办法原因:这是一个非托管的dll什么是托管的dll?就是用.net代码实现的dll,可以是用C#,VB.NET实现的什么是非托管的dll?就是不是用.net代码实现的d......
  • vs2022创建c语言的dll项目
    1.创建项目  2.创建完成不需要删除自动生成的文件3.修改项目属性右键单击--->c/c++--->常规----->附件包含目录------>这里不用 c/c++----->预处理器------->......
  • HOOK API DLL 注入
    一、序言对大多数的Windows开发者来说,如何在Win32系统中对API函数的调用进行拦截一直是项极富挑战性的课题,因为这将是对你所掌握的计算机知识较为全面的考验,尤其是一些在......