107

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?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
gemfield
  • 3,228
  • 7
  • 27
  • 28
  • 2
    possible duplicate of [Why/when is __declspec( dllimport ) not needed?](http://stackoverflow.com/questions/4489441/why-when-is-declspec-dllimport-not-needed) – Hans Passant Jan 14 '12 at 16:10

4 Answers4

149

__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 and dllexport. 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 use dllexport to mark a symbol as exported from a DLL, and you use dllimport 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:

#if COMPILING_DLL
    #define DLLEXPORT __declspec(dllexport)
#else
    #define DLLEXPORT __declspec(dllimport)
#endif

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 either Q_DECL_IMPORT or Q_DECL_EXPORT.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • __declspec is not properly "MS-specific" (it's much more "compiler specific) and some compilers use this declaration for multiple platform as well. Some of the attributes values are (dllexport / dllimports are MS specific, in fact, since DLL is MS lexicon). – Emilio Garavaglia Jan 14 '12 at 16:22
  • 11
    @Emilio: As far as I'm aware, Microsoft invented the `__declspec` notation as an extension to the C++ language. I believe that GCC now supports it, but that's primarily for compatibility reasons with Microsoft's compilers. And I don't understand how "MS-specific" is any different from "compiler specific". Microsoft wrote a C++ compiler and lots of people use it. It comes with Visual Studio. – Cody Gray - on strike Jan 14 '12 at 16:24
  • MS-specific means "specific to MS environment", while "compiler specific" means "specific to a given compiler, not to all". Now, since there are non-MS compiler using __declspec, it cannot be said -stricly speacking- MS specific. (note: there are some __declspec for GCC that realtes to Linux as well, so it's even not just a Windows issue...). What you say is historically true, but not "semantically". – Emilio Garavaglia Jan 14 '12 at 18:56
  • 1
    Neither `__declspec()` nor `dllimport/dllexport` are specific to Microsoft compilers. `__declspec` is used by a range of different vendor compilers for supporting compiler-specific extensions to the C++ language itself. Just about all C++ compilers that support Microsoft platforms support the `dllimport/dllexport` extension, but they are certainly not the only extensions available. – Remy Lebeau Jan 15 '12 at 06:19
  • 9
    Microsoft makes a compiler. It's called the "Microsoft C/C++ Optimizing Compiler", cl.exe. Lots of people erroneously refer to Visual Studio as if it is a compiler, but it's an IDE. I don't know why people are nit-picking about what "Microsoft-specific" means. It doesn't mean an "MS environment" (whatever that is), and it certainly doesn't mean "Windows". Yes, other compiler vendors now support the extension for compatibility with the installed base of code written targeting Microsoft compilers. As I said before, as far as I'm aware, Microsoft invented the syntax. That's the point made here. – Cody Gray - on strike Jan 15 '12 at 07:17
  • 2
    @CodyGray: Microsoft having invented it alone would not suffice. *However* Microsoft having invented it, no standard containing it, others only implementing it for compatibility and it being used primarily (if not exclusively) for programs targeting Microsoft Windows together make a very strong point for calling it "Microsoft specific" – celtschk Jan 15 '12 at 08:02
  • @CodeGray: So, to stay with yoyr assumpion C++ is "Stroustroup specific" ?!? __declspec is not present only in Microsoft compiler, hence isn'nt ANYMORE microsoft specific. At least for what the English dictinary tells about the word "specific". – Emilio Garavaglia Jan 16 '12 at 08:07
  • Stroustroup released C++ as an open standard. – Cody Gray - on strike Jan 16 '12 at 20:35
  • 8
    This is an awesome answer, especially the part about "because the same header file is generally used both when compiling the DLL and in client code"! Makes every aspect of the import/export-stuff crystal clear. – Ela782 Aug 17 '14 at 22:58
  • +1 to @Ela782, I couldn't get my head around it until I read that line. You use export when the "owner" of the header builds the lib/dll and import when the "client/consumer" uses it as interface to that lib. – Alejandro Nagy Jul 06 '17 at 20:50
  • Why are you @EmilioGaravaglia nitpicking so hard? It doesn't even add any useful information here. Everyone knows what the answer is talking about. This air of preachy arrogance "I am holier and smarter than thou" is why Stackoverflow is such a disgusting platform to contribute to. If you had nothing useful to add, just downvote and move on. – B_Dex_Float Jun 05 '23 at 15:57
35

__declspec(dllimport) is a storage-class specifier that tells the compiler that a function or object or data type is defined in an external DLL.

The function or object or data type is exported from a DLL with a corresponding __declspec(dllexport).

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
arx
  • 16,686
  • 2
  • 44
  • 61
  • 8
    Ok. Finally, after 2 hours of reading, i found the most satisfying, most concise, accurate to the point statement of what I want. – el psy Congroo May 25 '17 at 14:19
8

__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

Lewis Kelsey
  • 4,129
  • 1
  • 32
  • 42
-2

It means that the definition of the function is in a dynamic library. Refer to the documentation for more details and examples.

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434