How to generate DLL for ordinary Qt projects (including source code + comments)

Article directory

  • 1. Example diagram
  • 2. Contents that need to be modified in ordinary projects
  • 3. Source code (a TestDLL project was created, and the changes were mainly in the pro file and maindow.h file)
    • TestDLL.pro
    • mainwindow.h
    • mainwindow.cpp
    • mainwindow.ui
  • Summarize
  • related articles

1. Sample image

Compiling using different compilation modes will generate the “TestDll” folder in the corresponding compilation directory (add “DESTDIR = ./TestDll” to the pro file to specify the generation directory), and then specify it according to the target (if not specified, it will default to the project name), the corresponding library name is generated, as shown in the figure below.

2. Contents that need to be modified in ordinary projects

  1. First, let me explain that the “Normal project” here refers to a project that is created through Qt and can be run directly.
  2. Ordinary projects need to generate dll files and only need to change “TEMPLATE = app” to “TEMPLATE = lib” in the Qt pro file.
  3. However, through the second point, only dll files can be generated. If you want to generate lib files, you need to use Q_DECL_EXPORT/Q_DECL_IMPORT at the declaration location of the external class. strong> tag (of course lib can also be generated through config + = staticlib, but it does not apply here).
  4. Q_DECL_EXPORT is used to export classes or functions so that they can be used in dynamic link libraries.
  5. Q_DECL_IMPORT is used to import classes or functions in order to use the classes or functions exported through Q_DECL_EXPORT.

3. Source code (a TestDLL project was created, and the changes were mainly in the pro file and maindow.h file)

TestDLL.pro

The content added/changed in the pro file is as follows (note the TEST_DLL_FLAG macro below):

# Update the original app to lib
TEMPLATE=lib
# Define the test library tag (to make it clear that the current project is a normal project)
DEFINES + = TEST_DLL_FLAG

# Generate different names according to different compilation modes (usually files generated in debug mode end with d)
win32:CONFIG(release, debug|release): {<!-- -->
TARGET = TestDLL
}
else {<!-- -->
TARGET = TestDLLd
}
#Specify the directory where the library will be generated
DESTDIR = ./TestDll

The complete content is as follows:

#------------------------------------------------- ---
#
# Project created by QtCreator 2023-10-16T23:37:44
#
#------------------------------------------------

QT + = core gui
#Generate DLL
TEMPLATE=lib

greaterThan(QT_MAJOR_VERSION, 4): QT + = widgets


# Define the test library tag (to make it clear that the current project is a normal project)
DEFINES + = TEST_DLL_FLAG

# Generate different names according to different compilation modes (usually files generated in debug mode end with d)
win32:CONFIG(release, debug|release): {<!-- -->
TARGET = TestDLL
}
else {<!-- -->
TARGET = TestDLLd
}

#Specify the directory where the library will be generated
DESTDIR = ./TestDll

# 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

CONFIG+=c++11

SOURCES + = \
        main.cpp \
        mainwindow.cpp

HEADERS + = \
        mainwindow.h

FORMS + = \
        mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${<!-- -->TARGET}/bin
else: unix:!android: target.path = /opt/$${<!-- -->TARGET}/bin
!isEmpty(target.path): INSTALLS + = target

mainwindow.h

The defined TEST_DLL_FLAG macro is used to distinguish the export or import status. When the current project is a normal project, the TEST_DLL_FLAG macro will be recognized, and the content represented by TEST_DLL_MODE is Q_DECL_EXPORT, otherwise it is Q_DECL_IMPORT, which corresponds to export and import.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

//! Define library mode macro to distinguish between local and imported mode situations
//! Generally speaking, which class needs to be called outside the library, just add the mode macro in front of the definition of which class.
#ifdef TEST_DLL_FLAG
#define TEST_DLL_MODE Q_DECL_EXPORT
#else
#define TEST_DLL_MODE Q_DECL_IMPORT
#endif

#include <QMainWindow>

namespace Ui {<!-- -->
class MainWindow;
}

class TEST_DLL_MODE MainWindow : public QMainWindow
{<!-- -->
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{<!-- -->
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{<!-- -->
    delete ui;
}

mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QHBoxLayout" name="horizontalLayout">
    <item>
     <widget class="QLabel" name="label">
      <property name="font">
       <font>
        <pointsize>35</pointsize>
       </font>
      </property>
      <property name="text">
       <string>Test dll project</string>
      </property>
      <property name="alignment">
       <set>Qt::AlignCenter</set>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>400</width>
     <height>23</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

Summary

This ends the content of DLL generated by ordinary projects. How to use the exported dll and lib will be reflected in the next article.

Related articles

The use of DLL in Qt (associated DLL generation)

Friendly reminder – if you don’t understand, please be private. Let’s improve each other together.
(Creation is not easy, please leave a free like. Thank you o/)

Note: The article is a summary of the problems encountered by the author during the programming process. The content is for reference only. If there are any errors, please point them out.
Note: If there is any infringement, please contact the author to delete it.