How to publish pure C++ projects as dll in Qt (super detailed steps)

Directory

  • General creation method
  • Export ordinary function methods & call methods
  • Export methods of classes and their member functions & call methods

As we all know, we can export classes and functions in C++ projects to form .dll files for use by other programs. The following will explain how to use them in the Qt environment. .

First create a shared library, the steps are as follows:

In the next step, the class dialog box and so on will appear. Don’t worry about it, just click Create and delete the classes later.

After creating it, you will find that there is a header file containing global. This file defines __declspec(dllexport), __declspec(dllimport), etc., which can also be deleted (if you want to follow the method below, just delete it).

Benefit of this article,You can receive Qt development learning package and technical videos for free, including (Qt practical project video tutorial + code, C++ language basics, C++ design pattern , Introduction to Qt programming, QT signal and slot mechanism, QT interface development-image drawing, QT network, QT database programming, QT project practice, QSS, OpenCV, Quick module, interview questions, etc.) ↓↓↓↓↓↓See below↓ ↓Click at the bottom of the articleto receive the fee↓↓

There is an important step next. Please add it to the .pro file.

CONFIG + = dll //Even if your code is written as CONFIG + = staticlib, you must change it

Next let’s start with our specific creation method!

According to the operation of exporting dll, there are two modes:

  • Export common methods (can be called statically or dynamically after exporting)

The first is the header file content:

Header file:
When declaring a method, add __declspec(dllimport) in front of it, or you can use #define to define it. See the code:
//In order to share a header file with programs used in the future, __declspec(dllexport) is used when creating a dll, and __declspec(dllimport) is used when using a dll. You can write them separately.
#define TESTDLLSHARED_EXPORT __declspec(dllexport)
#ifdef TESTDLLSHARED_EXPORT
#else
#define TESTDLLSHARED_EXPORT __declspec(dllimport)
#endif

// Below I want to define 4 ordinary functions:
TESTDLLSHARED_EXPORT int test1();

TESTDLLSHARED_EXPORT int test2(void);

TESTDLLSHARED_EXPORT int test3(int a);

TESTDLLSHARED_EXPORT int test4(int a,int b);

Then implement the test1, test2, test3, and test4 methods in the corresponding cpp source files (for simplicity, I only output one sentence):

.cpp source file: //Remember to add the above header file
//Remember to add the iostream header file, otherwise cout cannot be used

int test1()
{
    std::cout<<"test1"<<std::endl;
}

int test2(void)
{
    std::cout<<"test2"<<std::endl;
}

int test3(int a)
{
    std::cout<<"test3"<<std::endl;
}

int test4(int a,int b)
{
    std::cout<<"test4"<<std::endl;
}

Next, you can create it. After the creation is successful (please check carefully if the creation fails, the code has been verified), you will find a .dll file with the same name as the project in your project output directory.

OK! Next we use this dll:

There are two calling methods when using dll, one is static calling and the other is dynamic calling.

  • Static call

First, create a regular C++ project and copy the .dll generated above to your project output directory (that is, together with the .exe file);

Next, open the .pro file in the regular C++ project and add the detailed .dll file address in the following format

LIBS + = project output path\dll file full name

Like mine is

LIBS + = D:\Desktop\Go\C + + learnProgram\Qt\build-test_dll-Qt-Release\release\HpTickDll.dll
D:\Desktop\Go\C++ learnProgram\Qt\build-test_dll-Qt-Release\release is my project output path, HpTickDll.dll is my dll file, when using Just change it

Next, copy the header file when creating the .dll file to the current project path and add it to the project. Note: If you do not follow my #define condition definition method above, please rewrite __declspec(dllimport).

Next, include the header file in the .cpp file, and you can use the previous functions as much as you like, such as directly using test1(), etc., just like you usually write.

  • Dynamic call

! ! ! Special note: We did not use extern “C” when creating, nor did we use the .def file to keep the function name unchanged (I have tried many times and still can’t use the .def file, please leave a message if you can), so dynamically The function name needs to be changed when calling! Because the compiler has changed the function name!

So, you must ask how do we know what the function name in the dll has become? Don’t worry, just search for “.dll viewer” on the Internet. They are everywhere. After downloading it, select the .dll file we just had and you can view it. Here are the new functions of our functions test1, test2, test3, and test4. Name (yours may be different from mine):

Please pay attention to the part in the red box (don’t worry about other things, there are other things in my file). These are the names of the four functions in the .dll file. I made a little guess, and the v at the end represents the parameter. It is of void type, and the number of i represents the number of int type parameters. The first letters are not clear (note: the number of parameters is not listed correctly, but we only need the correct function name, it does not affect it).

OK! That’s easy! See the steps:

It is also a regular C++ project, but the difference is that there is no need to add the sentence “LIBS + = project output path\dll file full name” in the .pro file.

Next, write the main code in the .cpp file (without adding the previous header file):

#include <iostream>
#include <windows.h>

int main()
{
    //First define a function pointer to receive functions with different parameters
    typedef int (CALLBACK *Fucv)();
    typedef int (CALLBACK *Fuci)(int);
    typedef int (CALLBACK *Fucii)(int,int);
    //Get the handle of the .dll file, which requires the support of the header file windows.h
    HINSTANCE hdll=LoadLibrary(L"testDll.dll"); //L refers to a wide string. If L is not written, an error will occur. Please check yourself for details.

    //Note that the function name in the .dll file must be used here.
    Fucv t1=(Fucv)GetProcAddress(hdll,"_Z5test1v");
    Fucv t2=(Fucv)GetProcAddress(hdll,"_Z5test2v");
    Fuci t3=(Fuci)GetProcAddress(hdll,"_Z5test3i");
    Fucii t4=(Fucii)GetProcAddress(hdll,"_Z5test4ii");

    //Now t1 executes the function of test1, and so on.
    t1();
    t2();
    t3(1);
    t4(1,2);

    FreeLibrary(hdll);

    return 0;
}

The above is the method of creating .dll and using .dll with ordinary functions. Does it seem that dynamic calling is troublesome? But it has many advantages (please check yourself), and it is said that the function name here can be realized by using the .def file without changing the name, saving a lot of trouble, but I have tried various methods, such as using DEF_FILE to add .def in .pro The file is still not working 55555, if you can, please leave a message!

  • Export the class and its member functions (it can be called statically after exporting. It will not be called dynamically for the time being. Some books say that classes do not support dynamic calling. There is talk on the Internet about writing a method in the class to return the class object. But I personally think that this approach is wrong, because at this time, you must use your own defined function pointer to define this return class object method, which is impossible to succeed [verified]. Of course, there may be a better method. Anyone who knows is welcome Exchange)

For classes, when creating: add the defined __declspec(dllexport) after class and in front of the class name; when using, replace it with __declspec(dllimport), or you can refer to the previous #define conditional definition method. Example:

#define HPTICKDLLSHARED_EXPORT __declspec(dllexport)
#ifdef HPTICKDLLSHARED_EXPORT
#else
#define HPTICKDLLSHARED_EXPORT __declspec(dllimport)
#endif

class HPTICKDLLSHARED_EXPORT HpTickDll //I defined the class HpTickDll here
{
public:
    int Start(); //Note that there is no need to add HPTICKDLLSHARED_EXPORT before the member function
    int GetTime();

private:

    LARGE_INTEGER li;
    LONGLONG start, end, freq;
    int useTime;
};

The method of static calling is the same as that of ordinary functions. You can directly use the class and its member functions (don’t forget to add the header file), so I won’t go into details.

Benefit of this article,You can receive Qt development learning package and technical videos for free, including (Qt practical project video tutorial + code, C++ language basics, C++ design pattern , Introduction to Qt programming, QT signal and slot mechanism, QT interface development-image drawing, QT network, QT database programming, QT project practice, QSS, OpenCV, Quick module, interview questions, etc.) ↓↓↓↓↓↓See below↓ ↓Click at the bottom of the articleto receive the fee↓↓