DLL,是 Dynamic Link Library的缩写,中文名 动态链接库。DLL是一个包含可由多个程序,同时使用的代码和数据的库。 本文简介DLL 概念,记录 DLL 工程创建与使用方法。
简介 动态链接库( Dynamic-link library,缩写为 DLL) 是微软公司在windows 系统中实现共享函数库概念的一种实现方式。所谓动态链接,就是把常用的公共函数封装到 DLL 文件中,当程序需要用到这些函数时,系统才会动态地将 DLL 加载到内存中使用。
调用方式主要分为两种:
静态加载: 启动时加载DLL:需要使用.h头文件和.lib文件
动态加载: 运行时加载DLL:使用LoadBibrary() GetProcessAddress()
动态链接库的扩展名: .dll, .ocx 或者 .drv(驱动程序)。
动态链接库的优势由于 DLL 可以在需要时加载,因此可以节约内存空间,提升运行效率;更新 DLL 不需要重新编译链接整个程序,仅更换 DLL、lib 、头文件等文件即可。调用方式定义外部接口不是所有 dll 中的函数都可以在装载后调用,需要向外开放的内容在声明时需要加前缀 __declspec(dllexport)我看到的现象是如果需要动态加载的函数,还额外需要定义在 extern "C" 函数体中静态加载静态加载 dll 是在程序启动时加载,需要使用.h头文件和.lib文件在应用程序中引入 dll 的头文件声名接口,引入库 lib 文件,在程序目录中包含 dll 文件,即可将 dll 中向外开放的接口当作正常接口使用动态加载可以在程序运行过程中随时动态加载 dll 中为动态加载开放的函数完整使用流程如下:声明函数指针 typedef DWORD(*MYDEMOW)();定义函数指针变量 MYDEMOW demo =动态加载DLL到内存 hmo = LoadLibrary(_T("DLL2.dll"));函数指针变量接收DLL中加载函数的地址 MYDEMOW demo= (MYDEMOW)GetProcAddress(hmo, "DEMOW")调用函数指针 demo();释放动态链接库 FreeLibrary(hmo);动态链接库搜索顺序 对于Windows,加载动态链接库时:
如果内存中已经有同module名的DLL,除非是DLL redirection或manifest,否则直接就用内存中这个DLL而不再搜索。如果DLL名字属于当前Windows版本的Known DLL,则必须用Known DLL。清单见 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs.如果DLL有依赖DLL,操作系统按缺省标准规则根据module名字搜索依赖DLL。即使第一个DLL指定了全路径。 Windows Desktop应用程序的DLL标准搜索序:
应用程序所在目录;系统目录。GetSystemDirectory函数返回该目录。16比特系统目录;Windows目录。使用GetWindowsDirectory函数返回该目录。当前(工作)目录;环境变量PATH中列出的目录。如果SafeDllSearchMode被禁止,则当前目录成为第二个被搜索的目录。创建 DLL以 Visual Studio 2017 环境为例:文件 -> 新建 -> 项目 -> Visual C++ -> Windows 桌面 -> 动态链接库。我给项目起名 dll_demo新建头文件 dll.h,在其中声明外界调用的类和接口,我在这里设置了几种示例,用于静态、动态调用测试:1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
#pragma once#ifdef CREATEDELL_API_DU#else #define CREATEDELL_API_DU _declspec(dllimport) //当编译时,头文件不参加编译,所以.cpp文件中先定义,后头文件被包含进来,因此外部使用时,为dllexport,而在内部编译时,则为dllimport#endif // 静态加载测试类class CREATEDELL_API_DU animal //需要被外界调用的类(父类){public: virtual int outDate() = 0; //纯虚函数 void getWide(int x); void getHigh(int y);protected: int wide; int high;};class CREATEDELL_API_DU cat :public animal //需要被调用的类(子类cat){public: int outDate();};class CREATEDELL_API_DU dog :public animal //需要被调用的类(子类dog){public: int outDate();};// 静态/动态 加载测试函数int square1(int x);extern "C"{ __declspec(dllexport) int square2(int x);}__declspec(dllexport) int square3(int x);//动态加载测试类class Math{public: virtual double add(double a, double b) = 0; virtual double substract(double a, double b) = 0; virtual double multiply(double a, double b) = 0; virtual double divide(double a, double b) = 0; virtual ~Math() {};};extern "C"{ __declspec(dllexport) Math* FactoryCreate(); __declspec(dllexport) void FactoryDestroy(Math* pmath);}class MathImplementation : public Math{public: double add(double a, double b); double substract(double a, double b); double multiply(double a, double b); double divide(double a, double b);};
新建 dll.cpp 源文件,在其中完成对外类、接口的实现
在源文件开头需要引入 pch.h
加入 #include "pch.h", 否则会报错
1错误 C1010 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "pch.h"”? dll_demo
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
#include "pch.h"#define CREATEDELL_API_DU _declspec(dllexport)#include
我选择了 Debug x86 平台,生成解决方案在项目文件夹可以看到生成的 dll , lib 等文件至此我们完成了 dll 的创建加载使用 DLL在已经生成好 dll 、 lib 、.h 后,我们就可以着手使用了创建 Visual C++ 空项目,取名 dll_load我们采用运用 dll,lib, .h 文件的方式调用 dll需要配置包含目录包含 dll.h加入 lib 文件所在路径,作为库目录添加 lib 文件作为依赖项 将dll 文件拷贝到项目源文件夹用于静态加载
创建源文件,起名 load.cpp
加入调用 dll 代码,其中包含了静态、动态加载 dll 函数、类的简单示例,一些需要注意的点我写在注释里了
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
#include
运行代码,看到调用 dll 得到的输出1234567891011121314151617181920212223242526
静态调用函数测试4949静态调用类测试1203-120.5动态加载DLL动态加载 dll 函数dllFuntest1 加载函数失败!dllFuntest3 加载函数失败!49动态加载、使用 dll 类3-120.5请按任意键继续. . .
错误记录1
Error C2375 'onnx_inference::initModel': redefinition; different linkage
在头文件中未给类定义添加CREATEDELL_API_DU修饰时,cpp中类成员函数会出现以上错误。参考资料https://baike.baidu.com/item/.dll/2133451?fr=aladdinhttps://blog.csdn.net/dou3516/article/details/124123127https://zh.wikipedia.org/wiki/动态链接库https://blog.csdn.net/qq_43615820/article/details/126895973https://www.cnblogs.com/zpchcbd/p/11900727.html