Why/when is __declspec( dllimport ) not needed?
It isn't required. It is an optimization, a hint to the compiler that the DLL is going to export the function pointer directly rather than just an entry in the IAT of the DLL. The exported function pointer for a function named foo() will be __imp_foo. Which allows it to generate better code, saving a function pointer load from the IAT and an indirect jump. It is a time optimization, not space.
This blog post has the details.
Why do we use __declspec(dllimport) when it seems so useless?
From the documentation:
Using __declspec(dllimport) is optional on function declarations, but the compiler produces more efficient code if you use this keyword. However, you must use __declspec(dllimport) for the importing executable to access the DLL's public data symbols and objects. Note that the users of your DLL still need to link with an import library.
what does __declspec(dllimport) really mean?
__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
.
what does __declspec(dllexport) do , when add it before a import function
First, think about what you need without the macro. If a class or
function is defined in module1, you need to declare it__declspec(dllexport)
in module1, and __declspec(dllimport)
in all
of the other modules. Including in the header file where it is
declared.
Since you don't want to maintain two different header files, and you
don't what conditional compilation all over the place, the best solution
is use a conditionally defined macro, e.g.:
#ifdef MODULE1
#define MODULE1_DECL __declspec(dllexport)
#else
#define MODULE1_DECL __declspec(dllimport)
#endif
When invoking the compiler, you only define MODULE1
in the project
module1; you don't define it in any other project. So when compiling
module1, MODULE1_DECL
expands to __declspec(dllexport)
, and when
compiling any other module, it expands to __declspec(dllimport)
.
Related Topics
C++11: How to Alias a Function
(How) How to Count the Items in an Enum
How to Set a Timeout on Blocking Sockets in Boost Asio
Is It Legal to Redefine a C++ Keyword
"No Newline at End of File" Compiler Warning
How to Handle Failure in Constructor in C++
C++ Boost: Undefined Reference to Boost::System::Generic_Category()
Audio Output with Video Processing with Opencv
Why Is It Ok to Return a 'Vector' from a Function
Performance of Qsort VS Std::Sort
Why Catch an Exception as Reference-To-Const
Check at Compile-Time If Template Argument Is Void
Difference Between Pointer to a Reference and Reference to a Pointer
Why Should I Use the "Using" Keyword to Access My Base Class Method