如何在 Qt C++ 中动态创建和加载库

How do I create and load lib dynamically in Qt C++

https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application 所述,我想创建 dll (Windows 10) 并使用 QLibrary 作为插件动态加载它。

在 Dependency Walker 中,我看到可以加载 exports 和 dll。但是 resolve 总是给我 0。我在网络上尝试了几个例子和 hinds,但没有成功。我做错了什么?

.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

TEMPLATE = lib
HEADERS += eurolite_dmx512_pro_mk2.h \
    Eurolite_DMX512_Pro_MK2_global.h
SOURCES += eurolite_dmx512_pro_mk2.cpp
DEFINES += EUROLITE_DMX512_PRO_MK2_LIBRARY

global.h

#ifndef EUROLITE_DMX512_PRO_MK2_GLOBAL_H
#define EUROLITE_DMX512_PRO_MK2_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(EUROLITE_DMX512_PRO_MK2_LIBRARY)
#  define EUROLITE_DMX512_PRO_MK2 Q_DECL_EXPORT
#else
#  define EUROLITE_DMX512_PRO_MK2 Q_DECL_IMPORT
#endif
#endif // EUROLITE_DMX512_PRO_MK2_GLOBAL_H

.h

#ifndef SHARED_H
#define SHARED_H

#include "Eurolite_DMX512_Pro_MK2_global.h"
#include <QDebug>

class Device
{
public:
    Device();
    void Testdll() {qDebug("OK");}
};

extern "C" EUROLITE_DMX512_PRO_MK2 int getVersion();
extern "C" EUROLITE_DMX512_PRO_MK2 QWidget *createWidget1();

int EUROLITE_DMX512_PRO_MK2 libStart(void)
{
    Device device;
    return 0;
}

#endif // SHARED_H

.cpp

#include <QWidget>
#include "eurolite_dmx512_pro_mk2.h"

Device::Device() {}

int getVersion()
{
    return 3;
}

QWidget *createWidget1()
{
    QWidget *widget = new QWidget();
    widget->resize(100, 100);
    return widget;
}

plugintest.c++

#include "dmxservice.h"

#include <QApplication>
#include <QDebug>
#include <QLibrary>
#include <QMessageBox>
#include <QFile>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    bool dmxLibAktiv = false;
    QLibrary dmxlib;

    QMessageBox msgBox;

    QFile file(QCoreApplication::applicationDirPath()+"/devices/Eurolite_DMX512_Pro_MK2.dll");
    if(file.exists()==true)
    {
        QLibrary dmxlib(QCoreApplication::applicationDirPath()+"/devices/Eurolite_DMX512_Pro_MK2.dll");
        if(dmxlib.load()==true)
        {
            dmxLibAktiv = dmxlib.isLoaded();
            msgBox.setText("DLL loaded!\n");
            msgBox.exec();
        }
        else
        {
            msgBox.setText("DLL not loaded!\n"+dmxlib.errorString());
            msgBox.exec();
        }
    }
    else
    {
        msgBox.setText("DLL not found '"+QCoreApplication::applicationDirPath()+"'!\n");
        msgBox.exec();
    }

    if (dmxLibAktiv) {
        typedef QWidget *(*CreateWidgetFunction)();
        CreateWidgetFunction cwf = CreateWidgetFunction(dmxlib.resolve("createWidget1"));
        if (cwf) {
            QWidget *widget = cwf();
            if (widget)
                widget->show();
        } else {
            qDebug() << "Could not show widget from the loaded library";
        }
    }
    DmxService w;
    w.show();
    return a.exec();
}

您在 if (file.exists()) 分支中创建了本地 QLibrary dmxlib(...);。所以外部 dmxlib 实例永远不会被初始化。

ADDED:不要在if块中重新声明变量,改用setFileName()

QLibrary dmxlib;
...
if (file.exists()) {
  dmxlib.setFileName(QCoreApplication::applicationDirPath()+"/devices/Eurolite_DMX512_Pro_MK2.dll");
  if (dmxlib.load())
    ....
}

// ... use dmxlib