I saw the Qt source code like this:
class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
Which Q_CORE_EXPORT
macro defines like below:
define Q_DECL_IMPORT __declspec(dllimport)
So what does __declspec(dllimport)
really mean?
I saw the Qt source code like this:
class Q_CORE_EXPORT QBasicAtomicInt
{
public:
...
};
Which Q_CORE_EXPORT
macro defines like below:
define Q_DECL_IMPORT __declspec(dllimport)
So what does __declspec(dllimport)
really mean?
__declspec(dllexport)
tells the compiler to inform the linker that these symbols need to be placed in the export table (when compiling the .dll), and to put those symbols in the import library .lib.
When compiling the program that links with the .dll, __declspec(dllimport)
tells the compiler to produce a rip-relative memory-indirect call (which the linker will fill resolve to point to the import table) rather than the usual relative direct instruction to the undefined function (which, as it can't modify the instruction, the linker inserts the relative address of a thunk and then creates the thunk, inside which it places the rip-relative memory-indirect jump to the function pointer in the import table). This is a code size and speed optimisation. It is the import library .lib that tells the linker which symbols are exported by the .dll and is used as a guide to create the import table based on the intersection of those with the matching extern symbol table entries and create any necessary thunks in the .text segment.
https://learn.microsoft.com/en-us/cpp/build/importing-function-calls-using-declspec-dllimport?view=vs-2019 https://learn.microsoft.com/en-us/cpp/build/importing-data-using-declspec-dllimport?view=vs-2019 https://stackoverflow.com/a/4490536/7194773
__declspec
is a Microsoft-specific attribute that allows you to specify storage-class information.(Nitpicker's Corner: However, a number of other compiler vendors—e.g. GCC—now support this language extension for compatibility with the installed base of code that was written targeting Microsoft's compilers. Some even provide additional storage-class attributes.)
Two of those storage-class attributes that can be specified are
dllimport
anddllexport
. These indicate to the compiler that a function or object is imported or exported (respectively) from a DLL.More specifically, they define the DLL's interface to the client without requiring a module-definition (
.DEF
) file. Most people find it much easier to use these language extensions than to create DEF files.For obvious reasons,
__declspec(dllimport)
and__declspec(dllexport)
are generally paired with one another. You usedllexport
to mark a symbol as exported from a DLL, and you usedllimport
to import that exported symbol in another file.Because of this, and because the same header file is generally used both when compiling the DLL and in client code that consumes the DLL's interface, it is a common pattern to define a macro that automatically resolves to the appropriate attribute specifier at compile-time. For example:
And then marking all of the symbols that should be exported with
DLLEXPORT
.Presumably, that is what the
Q_CORE_EXPORT
macro does, resolving to eitherQ_DECL_IMPORT
orQ_DECL_EXPORT
.