动态库的特点
运行的时候独立存在(有自己的主函数,但是需要依附别的程序执行),是一个独立的进程,有着自己独立的空间 源码不会被link.exe(链接)到执行程序 使用的时候加载 .dll 文件包含两个部分每一个部分是文件头(存函数的 pointer[下标0,函数名字,函数指针]),一个是正文(存源码)如图
编号 | 函数名字 | 函数相对地址 |
---|---|---|
0 | add | af9090 |
1 | sub | aa8888 |
函数源码 |
配套生成的lib文件存{对应 .dll文件的文件名,[导出函数的名字,下标编号]}配到的lib文件如图
相应dll文件的名字
0add
1sub
dll 比较 lib
1. lib 是将代码嵌入到程序,使用的程序越多,会有多分代码,体积就会在增大,动态库只需要存在一份,其他程序通过函数的地址使用 2. lib 发生变化之后,需要重新链接嵌入代码。dll只要函数的定义(或者地址)没有变化,dll程序不需要重新链接 3. 在link的时候 lib 的源码就被link在了 exe 里面,此时的lib文件就可以删除了,而dll的话,就是把指针放进去
导出dll库程序
1. 方法一:申明导出:使用 _declspec(dllexport)导出函数{在需要导出的函数前面加上这个关键字}[dll编译之后会生成生成名字相同的lib文件,用来作为动态库的映射使用,于lib库不完全相同]
_declspec(dllexport) int add(int a,int b) { //导出的是地址 return a + b; }
2. 方法二:模块定义文件 .def(此时不需要加_declspec(dllexport))[此时就不会给我们改名字了] LIBRARY EXPORTS sub @1 XXX @2
使用动态库
隐式链接(操作系统让dll执行) 1. 需要使用动态库文件的函数原型前申明 _declspec(dllimport) 2. 导入dll的lib文件[#pragma comment(lib,"../x64/debug/cDll.lib")] 3. 调用 显式链接(程序员让dll执行,此时不需要使用#pragma comment导入对应的lib文件) 1. 定义函数指针[接收函数的指针] 2. 加载动态库[让动态库进内存]{HMODULE|HINSTANCE LoadLibrary(LPCTSTR lpFileName); 返回dll实例句柄} 3. 获取函数地址[FARPROC GetProcAddress();//成功返回函数加载后内存绝对地址] 4. 使用函数[] 5. 卸载动态库[BOOL FreeLibrary(HMODULE hModule);//释放空间]
隐式链接dll文件测存放位置
1. 与可执行文件在同一目录下面(强烈建议) 2. 当前项目的目录下面 3. windows 4. windows/system32 5. windows/system 6. 环境变量指定的path目录
使用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步