前言

 

在程序编码时,经常会用到动态库(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,拜拜了~