前言
在程序编码时,经常会用到动态库(DLL),比如分享自己的写的功能代码或者使用第三方的插件时。之前我只会最常用的加载方式(静态加载),后来在项目中要求动态加载,才学会了动态加载的方式。但是为什么要用不同的加载动态库方式呢?接下来,我们一起来探索它的答案。
两种方式介绍
1.传统常用的方式(静态加载)
静态调用前提是在编译之前已经明确知道调用DLL中的哪些函数,需要lib和相应的导入头文件*.h。编译时,在目标文件中只保留必要的链接信息,而不含DLL函数的代码;当程序执行时,利用链接信息加载DLL函数代码并在内存中将其连接入调用程序的执行空间中,其主要目的是便于代码共享。
平时,在庞大的项目中,我们需要配合工作将一些公用的功能封成dll,为了便于大家的使用。一般功能比较复杂的dll,通常使用静态加载的方式,一般情况下,dll的头文件都会写清楚暴露的函数说明,这样便于对功能的理解和代码的共享。
至于Qt Creator和VS静态加载动态库(dll)的配置,我这里就不赘述了,网上有很多,下面我提供了网友的教程的链接,便于懒癌患者的使用。
Qt Creator和VS的配置:
2.动态加载(QLibrary)
动态调用主要通过API函数(Window LoadLibrary、GetProcAddress、FressLibrary)来调用程序运行后需要的DLL函数,节省内存空间。QT中,则主要通过QLibrary进行动态加载(适用于跨平台)。
一般dll功能相较简单、比较好理解、较小时,通常使用动态加载的方式,这种方式只需要将dll放到运行目录下,或者固定路径下,其他就不需配置了。下面我介绍一下两种方式
Qt方式加载:
用Qt的方式,主要用到类QLibrary,它在运行时加载共享库,具体代码如下
QLibrary myLib("mylib");
//构造函数加载路径下的dll或者使用setFileName函数来加载路径下的dll
// myLib.setFileName("mylib");
//判断是否加载成功
if(myLib.load())
{
//创建函数指针与需加载的函数对应 typedef 返回值 (*函数指针名)(入参)
typedef void (*MyPrototype)();
MyPrototype myFunction = (MyPrototype) myLib.resolve("mysymbol");
if (myFunction)
myFunction();
//如果后续不再需要使用dll,则需要释放
myLib.unload();
}
纯C++(windows)方式加载:
typedef void (*MyPrototype)();
HINSTANCE hDLL;//DLL句柄
MyPrototype myFunction;//函数指针
hDLL = LoadLibrary(TEXT("mylib"));
if(hDLL)
{
myFunction = (MyPrototype)GetProcAddress(hDLL, TEXT("mysymbol"));
if (myFunction)
myFunction();
FreeLibrary(hDLL);
}
结束语
差不多就到这里吧,最常用的dll,拜拜了~