Is Q_DECL_EXPORT macro necessary?
-
Hi,
I create simple, shared library and simple app, which use that library.
Libary:
#ifndef BIBLIOTEKANAZWA_H #define BIBLIOTEKANAZWA_H #include "bibliotekaNazwa_global.h" extern "C" int suma(int a,int b); #endif // BIBLIOTEKANAZWA_H
App:
#include "bibliotekanazwa.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); qInfo()<<suma(2,3); }
Of course I added INCLUDEPATH and LIBS to .pro file. And it works - I see correct result of function
suma
.But in docs I see:
Depending on your target platform, Qt provides special macros that contain the necessary definitions: Q_DECL_EXPORT must be added to the declarations of symbols used when compiling a shared library. Q_DECL_IMPORT must be added to the declarations of symbols used when compiling a client that uses the shared library.
I don't add Q_DECL_EXPORT \ BIBLIOTEKANAZWA_EXPORT, and it works. So I have to add this macro?
-
The defaults for symbols visibility are platform and toolchain specific.
On Windows with MSVC all symbols are not exported by default and require explicit marking with
__declspec(dllexport)
. If you compile with MSVC your function will not be exported the way you have it now.With MinGW it's a bit more complicated. Symbols are by default exported, so require no extra annotation and that's what you're seeing. MinGW also has a linker flag that lets you hide all exports by default, like MSVC:
-fvisibility=hidden
. When you use it you need to explicitly mark a symbol to be exported with attribute__attribute__ ((dllexport))
. There's a weird quirk though that if you don't explicitly mark any symbol for export all symbols will be exported whether the linker flag is passed or not (probably for compatibility with older code).In general it's a good idea to keep your library interface as minimal as possible. This is good for internal optimization of the library and allows for better control over future modifications you might want to make. My suggestion is to always make your libraries not export symbols by default.
Q_DECL_EXPORT
is a macro that expands to either the MSVC or MinGW specific attribute to let you write portable code, so you should use it. Similarly, if you're using qmake, you can addCONFIG += hide_symbols
in your pro file to add the toolchain specific linker flags to hide symbols by default. -
@TomNow99 said in Is Q_DECL_EXPORT macro necessary?:
and it works
Is it a shared library?
Yourextern "C"
make it visible from the outside. But this works only for C functions. -
@Christian-Ehrlicher
Hmmm,After build that "library" I have 3 files:
bibliotekaNazwa.dll
bibliotekanazwa.o
libbibliotekaNazwa.a
And I add this files to my app like this:
INCLUDEPATH+="C:/Users/tom/Documents/bibliotekaNazwa"
LIBS += -LC:\Users\tom\Documents\build-bibliotekaNazwa-Desktop_Qt_5_15_1_MinGW_64_bit-Release\release
LIBS += -lbibliotekanazwaI add folder
C:\Users\tom\Documents\build-bibliotekaNazwa-Desktop_Qt_5_15_1_MinGW_64_bit-Release\release
to path.EDIT:
So I think this is shared library -
Hi,
I create simple, shared library and simple app, which use that library.
Libary:
#ifndef BIBLIOTEKANAZWA_H #define BIBLIOTEKANAZWA_H #include "bibliotekaNazwa_global.h" extern "C" int suma(int a,int b); #endif // BIBLIOTEKANAZWA_H
App:
#include "bibliotekanazwa.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); qInfo()<<suma(2,3); }
Of course I added INCLUDEPATH and LIBS to .pro file. And it works - I see correct result of function
suma
.But in docs I see:
Depending on your target platform, Qt provides special macros that contain the necessary definitions: Q_DECL_EXPORT must be added to the declarations of symbols used when compiling a shared library. Q_DECL_IMPORT must be added to the declarations of symbols used when compiling a client that uses the shared library.
I don't add Q_DECL_EXPORT \ BIBLIOTEKANAZWA_EXPORT, and it works. So I have to add this macro?
@TomNow99 said in Is Q_DECL_EXPORT macro necessary?:
Of course I added INCLUDEPATH and LIBS to .pro file. And it works - I see correct result of function
suma
.As @Christian-Ehrlicher said, you can see
suma
because you usedextern "C"
.However, notice that you cannot see
MainWindow
. -
The defaults for symbols visibility are platform and toolchain specific.
On Windows with MSVC all symbols are not exported by default and require explicit marking with
__declspec(dllexport)
. If you compile with MSVC your function will not be exported the way you have it now.With MinGW it's a bit more complicated. Symbols are by default exported, so require no extra annotation and that's what you're seeing. MinGW also has a linker flag that lets you hide all exports by default, like MSVC:
-fvisibility=hidden
. When you use it you need to explicitly mark a symbol to be exported with attribute__attribute__ ((dllexport))
. There's a weird quirk though that if you don't explicitly mark any symbol for export all symbols will be exported whether the linker flag is passed or not (probably for compatibility with older code).In general it's a good idea to keep your library interface as minimal as possible. This is good for internal optimization of the library and allows for better control over future modifications you might want to make. My suggestion is to always make your libraries not export symbols by default.
Q_DECL_EXPORT
is a macro that expands to either the MSVC or MinGW specific attribute to let you write portable code, so you should use it. Similarly, if you're using qmake, you can addCONFIG += hide_symbols
in your pro file to add the toolchain specific linker flags to hide symbols by default. -
Hi,
In addition to @Chris-Kawa great explanation, you can find how to properly use these macro in the create a shared library with Qt chapter in the Qt documentation.