VisualStudio&QT 动态库、静态库以及QT Plugin插件创建和加载方法

一、动态库创建以及静态加载方法

1. 创建动态库

(1)编写好.h和.cpp文件

(2)项目->属性->配置属性->常规->配置类型(动态库.dll)

 

2. 动态库静态加载方法

(1)包含编写好的.h文件

(2)pragma comment(lib, "../../../../")后面问lib库所在的路径

#pragma comment(lib, "../x64/Debug/dynamicLibrary.lib")

 

二、动态库创建以及动态加载方法

1. 创建动态库

同上述

2. 动态库动态加载方法

(1)添加主程序入口函数

注意:

.lib可随意放置,使用时,指定正确的路径即可

放置.dll文件在和.exe文件同一目录下

1)使用Windows库函数加载dll

2)LoadLibraryA 加载dll

3)GetProcAddress 获取函数地址

4)FreeLibrary 释放句柄

代码示意main函数

#include"add.h"
#include <stdio.h>
#include <iostream>
#include <Windows.h>
//#pragma comment(lib, "../x64/Debug/dynamicLibrary.lib")		// 动态库静态加载

//动态库动态加载
int main()
{
	HINSTANCE h = LoadLibraryA("dynamicLibrary.dll");//第一步
	typedef int(*FunPtr)(int a, int b);//定义函数指针
	if (h == NULL)
	{
		FreeLibrary(h);
		printf("load lib error\n");
	}
	else
	{
		FunPtr funPtr = (FunPtr)GetProcAddress(h, "add");//第二步
		if (funPtr != NULL)
		{
			int result = funPtr(8, 3);
			printf("8 + 3 =%d\n", result);
		}
		else
		{
			printf("get process error\n");
			printf("%d", GetLastError());
		}
		FreeLibrary(h);//第三步
	}
	system("pause");
}

================================下面介绍QT中plugin插件的创建以及使用===============================

 

三、静态库创建以及加载方法

1. 创建静态库

1)编写好.h和.cpp文件

(2)项目->属性->配置属性->常规->配置类型(静态库.lib)

2. 静态库加载方法

(1)包含编写好的.h文件

(2)pragma comment(lib, "../../../../")后面问lib库所在的路径

 

=====================以下为QT中动态库以及静态库加载方法====================

一、QT动态库创建

1. projects->library->共享库,建立如下所示的项目

2. 头文件

//testdynamiclib.h

#ifndef TESTDYNAMICLIB_H
#define TESTDYNAMICLIB_H

#include "testdynamiclib_global.h"

class TESTDYNAMICLIBSHARED_EXPORT TestDynamicLib
{

public:
    TestDynamicLib();
    void MyDynamicLib();
};

#endif // TESTDYNAMICLIB_H

3. .cpp文件

#include "testdynamiclib.h"


TestDynamicLib::TestDynamicLib()
{
}

void TestDynamicLib::MyDynamicLib()
{
    qDebug("test dynamic lib !");
}

 

二、QT静态库创建

1. projects->library->静态链接库

2. 头文件

#ifndef TESTSTATICLIB_H
#define TESTSTATICLIB_H
#include <qdebug.h>


class TestStaticLib
{

public:
    TestStaticLib();
    void TestMyStaticLib();
};

#endif // TESTSTATICLIB_H

3. cpp文件

#include "teststaticlib.h"


TestStaticLib::TestStaticLib()
{
}

void TestStaticLib::TestMyStaticLib()
{
    qDebug() << "test static lib !";
}

 

三、QT动态库和静态库调用

1. 包含头文件

#include <QCoreApplication>
#include <qdebug.h>
#include "../testDynamicLib/testdynamiclib.h"
#include "../testStaticLib/teststaticlib.h"
#include "../testDynamicLib/testdynamiclib_global.h"

2. 更改pro文件

(1)右击项目添加库

(2)添加如图所示的lib库文件

3. main函数文件

#include <QCoreApplication>
#include <qdebug.h>
#include "../testDynamicLib/testdynamiclib.h"
#include "../testStaticLib/teststaticlib.h"
#include "../testDynamicLib/testdynamiclib_global.h"

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

    // 动态库调用
    TestDynamicLib dynamiclib;
    dynamiclib.MyDynamicLib();

    // 静态库调用
    TestStaticLib staticlib;
    staticlib.TestMyStaticLib();





    return a.exec();
}

===============================QT Plugin的创建以及使用===================================

0 . 简介

Qt为创建插件提供了两个api:

1、为Qt本身编写扩展的高级API:自定义数据库驱动程序、图像格式、文本编解码器、自定义样式等等。

2、用于扩展Qt应用程序的低级API。

例如,如果您想编写一个定制的QStyle子类并让Qt应用程序动态地加载它,那么您将使用更高级别的API。

由于较高级别的API构建在较低级别的API之上,因此两者都存在一些共同的问题。

一、高级API:编写Qt扩展

编写扩展Qt本身的插件是通过子类化适当的插件基类、实现一些函数和添加宏来实现的。

二、低级API:扩展Qt应用程序

不仅Qt本身,Qt应用程序也可以通过插件进行扩展。这要求应用程序使用QPluginLoader检测和加载插件。在这种情况下,插件可以提供任意的功能,不限于数据库驱动程序、图像格式、文本编解码器、样式和其他扩展Qt功能的插件类型。

通过插件使应用程序可扩展涉及以下步骤:

1、定义一组用于与插件对话的接口(只有纯虚函数的类)。

2、使用Q_DECLARE_INTERFACE()宏告诉Qt的元对象系统关于接口的信息。

3、在应用程序中使用QPluginLoader来加载插件。

4、使用qobject_cast()测试插件是否实现给定的接口。

编写插件包括以下步骤:

1、声明一个插件类,它继承自QObject和插件想要提供的接口。

2、使用Q_INTERFACES()宏告诉Qt的元对象系统关于接口的信息。

3、使用Q_PLUGIN_METADATA()宏导出插件。

4、使用合适的.pro文件构建插件。

一. QT plugin的创建

1. 插件接口的设计,图片为文件结构。创建一个plugin主工程,在主工程中创建接口文件

 接口文件代码为

// plugindemopluginin

#ifndef PLUGINDEMOPLUGIN_H
#define PLUGINDEMOPLUGIN_H
#include <QObject>

class QtPluginDemoInterface

{

public:

    virtual ~QtPluginDemoInterface() {}

    //接口中声明一个打印函数

    virtual void printMessage(const QString& message) = 0;

};

#define QDesignerCustomWidgetInterface_iid "org.qt-project.QtPluginDemoInterface"

Q_DECLARE_INTERFACE(QtPluginDemoInterface, QDesignerCustomWidgetInterface_iid)

#endif // PLUGINDEMOPLUGIN_H

2. 修改主工程文件为

 

// plugindemo.h

#ifndef PLUGINDEMO_H
#define PLUGINDEMO_H

#include "plugindemoplugin.h"


class plugindemo : public QObject, QtPluginDemoInterface
{
    Q_OBJECT
#if QT_VERSION >= 0x050000
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QGenericPluginFactoryInterface" FILE "plugindemo.json")    // 使用Q_PLUGIN_METEDATA() 宏导出这个插件
#endif // QT_VERSION >= 0x050000
    Q_INTERFACES(QtPluginDemoInterface)        // 使用Q_INTERFACE() 宏告诉Qt元对象系统这个插件实现了哪些接口
public:
    explicit plugindemo(QObject *parent = nullptr);
    virtual void printMessage(const QString& message) override;
};

#endif // PLUGINDEMO_H

cpp文件

// plugindemo.cpp

#include "plugindemo.h"
#include <qdebug.h>


plugindemo::plugindemo(QObject *parent) :
    QObject(parent)
{
}

void plugindemo::printMessage(const QString &message)
{
    //在派生类中实现打印函数

    qDebug() << "---------------This is QtPluginDemoInterface Demo Test--------------" << message;
}

#if QT_VERSION < 0x050000
Q_EXPORT_PLUGIN2(plugindemo, plugindemo)
#endif // QT_VERSION < 0x050000

3. pro文件需要更改生成库文件的目录

#-------------------------------------------------
#
# Project created by QtCreator 2020-02-26T16:09:19
#
#-------------------------------------------------

QT       += core gui

TARGET = plugindemo
TEMPLATE = lib
CONFIG += plugin

DESTDIR = $$[QT_INSTALL_PLUGINS]/generic

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
        plugindemo.cpp

HEADERS += \
        plugindemo.h \
    plugindemoplugin.h
DISTFILES += plugindemo.json 
DESTDIR =./Mydll            // 设置库文件生成目标文件夹

unix {
    target.path = /usr/lib
    INSTALLS += target
}

 

 二. QT plugin插件的使用

1. 包含接口文件的头文件

#include <QCoreApplication>
#include <qplugin.h>
#include <qpluginloader.h>
#include "../plugindemoplugin.h"
#include <QDebug>

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

    //第一种方法

    //    QCoreApplication::addLibraryPath("../plugins");//将程序的插件路径添加到Qt的搜索路径中

    //    QPluginLoader loader("MyPlugin.dll");

    // 第二种方法
    QPluginLoader loader("../plugindemo/Mydll/plugindemo.dll");
    if(loader.load())
    {
        QObject* obj = loader.instance();
        if(obj!=0)
        {
            // 使用qobject_cast() 函数检测该插件是否实现了特定的接口
            QtPluginDemoInterface *plugin = qobject_cast<QtPluginDemoInterface*>(obj);
            if(plugin!=0)
            {
                //QString test = plugin->printMessage("haha");
                //qDebug("haha%s", plugin->printMessage("hahahaha"));
                qDebug() << plugin->printMessage("success");
            }
        }
        delete obj;

    }
    else
    {
        qDebug() << "加载插件失败...";
    }
    return a.exec();
}

2. 加载动态库,有上文代码两种方式。

.pro文件中要包含生成的库

QT -= gui

CONFIG += c++11 console
CONFIG -= app_bundle

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
        main.cpp

HEADERS +=


win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../plugindemo/Mydll/ -lplugindemo

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

三. qt工程合并的方式

1. 上文分别新建consoleplugin.pro和plugindemo.pro两个工程,过于分散,可以将其放在一个工程中

方式1:

(1)新建一个文件夹,创建一个plugintest.pro文件

(2)将两个项目的文件夹放入plugintest文件夹

(3)更改plugintest.pro文件

TEMPLATE = subdirs


QMAKE_LFLAGS_DEBUG += /NODEFAULTLIB:library

SUBDIRS += \
    plugindemo/plugindemo.pro \
    consoleplugin/consoleplugin.pro

方式2:

(1)新建一个项目

(2)在.pro文件中加入下面两句话,则可以直接在QT中新建子工程。

TEMPLATE = subdirs
QMAKE_LFLAGS_DEBUG += /NODEFAULTLIB:library

 

 

REF

1. C++静态库与动态库的区别?(https://blog.csdn.net/dd_hello/article/details/81782934

2. visual studio上C++库加载方式及方法:动态库静态加载、动态库动态加载、静态库加载(https://blog.csdn.net/u014140383/article/details/103864386?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

3. 在Visual Studio 2017下实现动态库加载(https://blog.csdn.net/Liut2016/article/details/81171375

4. QT中将项目生成库文件(http://www.freesion.com/article/693416710/

5. QT调用动态链接库实例(https://blog.csdn.net/roman1232008/article/details/17074371?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

6. QT生成动态链接库及调用详细步骤(https://blog.csdn.net/u011236602/article/details/80835575?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

7. QT Creator 如何建立动态链接库和使用的方法(详细的图文教程以及错误的讲解)(https://blog.csdn.net/qq_34837137/article/details/52277447

8. QT 调用 DLL 方法(三种方法)(https://blog.csdn.net/zhangbaoqiang1/article/details/82348930?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

9. QT 动态库和静态库的实现和调用https://blog.csdn.net/nanfeibuyi/article/details/80417194?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

===================QTplugin插件的创建以及使用=================================

10. 如何创建Qt插件(https://blog.csdn.net/wei375653972/article/details/86645989?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

11. qt插件Plugin生成与使用(https://blog.csdn.net/x85371169/article/details/79276924

12. QT之插件Plugin生成与使用(https://blog.csdn.net/ly305750665/article/details/78680647?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

13. QT之插件得使用(https://blog.csdn.net/zhoudonghao4381/article/details/102647985?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

 

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值