Qt 调用 dll 及与 plugin 的区别联系

目录 Content
[hide]

Qt 可以调用 dll, 插件可以dll形式存在。但是插件的话,要有个 interface 将 app 和 plugin 耦合起来。(此处说 dll 是特指在 Win 平台下)

应用场景:将类、函数封装成dll,供调用。

主要参考: https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application

一、显式调用

需要指定头文件 .h 和 库文件 .lib 的位置,即可编译。

指定可以手写,也可以用向导添加

win32:CONFIG(release, debug|release): LIBS += -L$$PWD/./ -ltest
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/./ -ltestd

INCLUDEPATH += $$PWD/.
DEPENDPATH += $$PWD/.

二、隐式调用

使用 QLibrary 加载 动态库文件。 *.h 和 *.lib 不需要。

    QLibrary library("qlibraryLibrary.dll");
    if (!library.load())
        qDebug() << library.errorString();
    if (library.load())
        qDebug() << "library loaded";
    
    typedef QWidget *(*CreateWidgetFunction)();
    CreateWidgetFunction cwf = (CreateWidgetFunction) library.resolve("createWidget1");

    if (cwf) {
        QWidget *widget = cwf();
        if (widget)
            widget->show();
    } else {
        qDebug() << "Could not show widget from the loaded library";
    }

对于一去二三里的例子,代码综合了类和外部函数的使用

#include <QApplication>
#include <QLibrary>
#include <QDebug>
#include "sharedlibrary.h"
#include <QMessageBox>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QLibrary mylib("SharedLibrary.dll");

    if (mylib.load())
    {
        qDebug() << "library loaded";

        //!class
        typedef SharedLibrary* (*GetSharedLibrary)();//定义函数指针,获取类TestDLL对象; 需要头文件 sharedlibrary.h
        GetSharedLibrary getSharedLibrary = reinterpret_cast<GetSharedLibrary>(mylib.resolve("getSharedLibrary"));
        if (getSharedLibrary)
        {
            SharedLibrary *pLib = getSharedLibrary();
            pLib->updateBackgroud();
            pLib->resize(400,200);
            pLib->subtract(100, 40);
            pLib->show();
            pLib->setWindowTitle("Test ShareLibrary");
        }else{
            qDebug() << "Could not show widget from the loaded library";
        }

        //! Function
        typedef int (*Fun)(int, int); //定义函数指针,int add(int a,int b);
        Fun add = reinterpret_cast<Fun>(mylib.resolve("add"));

        if (add)
        {
            int nResult = add(51, 5);
            QMessageBox::information(nullptr, "Tip", QString::number(nResult));
        }else{
            qDebug() << "Could not add from the loaded library";
        }

    }else{
        qDebug() << mylib.errorString();
    }


    return a.exec();
}

三、改进

注意到提示旧的转变风格,改为 即可。

C++ 有4种转换

dynamic_cast <new_type> (expression)
reinterpret_cast <new_type> (expression)
static_cast <new_type> (expression)
const_cast <new_type> (expression)

 

延伸阅读

  • QT插件和普通动态库的差别?
    https://bbs.csdn.net/topics/390843246?page=1
  • Qt之创建并使用共享库
    http://blog.sina.com.cn/s/blog_a6fb6cc90102vsdn.html
  • How to create a library with Qt and use it in an application
    https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application
  • C#和C++ 有关DLL的
    https://blog.csdn.net/qq_36196748/article/details/82756551
    显式(静态)调用:LIB+DLL+.H ,注意.H中的dllexport改为dllimport
    隐式(动态)调用:DLL+函数原型声明,先LoadLibrary,再GetProcAddress(即找到DLL中的函数的地址),不用后FreeLibrary;
    使用C++/clr语法,采用正确的访问托管对象,即:使用“^”,而不是用“*”
  • 用C++调用C#生成的dll(动态链接库文件)
    https://blog.csdn.net/qq_36196748/article/details/81218214
  • Qt5的插件机制(5)–QLibrary类与QPluginLoader类
    https://blog.csdn.net/NewThinker_wei/article/details/41292069

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.