Error: function definition is marked dllimport
Categories:
Resolving 'function definition is marked dllimport' in C++ and Qt

Understand and fix the common C++ compilation error 'function definition is marked dllimport' when working with DLLs, especially in Qt projects.
The error message "function definition is marked dllimport" is a common pitfall for C++ developers working with Dynamic Link Libraries (DLLs), particularly in cross-platform frameworks like Qt. This error typically arises when the compiler encounters a function definition that has been incorrectly marked for import, rather than export, from a DLL. This article will demystify the __declspec(dllimport)
and __declspec(dllexport)
keywords, explain why this error occurs, and provide practical solutions to resolve it in your C++ and Qt projects.
Understanding dllimport
and dllexport
In Windows programming, __declspec(dllimport)
and __declspec(dllexport)
are Microsoft-specific extensions used to declare functions, variables, or classes as being imported from or exported to a DLL. These keywords are crucial for the linker to correctly resolve symbols when building executables or other DLLs that depend on your library.
__declspec(dllexport)
: This keyword is used when defining a function or class within the DLL project itself. It tells the compiler to place the function's name in the DLL's export table, making it available for other modules to link against.__declspec(dllimport)
: This keyword is used when declaring a function or class in a header file that will be included by a client application (or another DLL) that uses your DLL. It tells the compiler that the definition for this symbol will be found in an external DLL, allowing it to generate more efficient code by avoiding an extra level of indirection.
flowchart TD subgraph DLL Project A[Source Code (.cpp)] --> B{__declspec(dllexport)} B --> C[DLL Export Table] end subgraph Client Project D[Header File (.h)] --> E{__declspec(dllimport)} E --> F[Client Executable/DLL] end C --"Provides Symbols"--> F
Flow of dllexport
and dllimport
in DLL creation and usage
The Root Cause of the Error
The error "function definition is marked dllimport" occurs when you attempt to define a function (i.e., provide its implementation) while it is simultaneously marked with __declspec(dllimport)
. The compiler expects dllimport
declarations to refer to symbols whose definitions reside outside the current compilation unit, typically in a separate DLL. When it finds a definition for an dllimport
-marked symbol, it flags this as an error because it's a logical contradiction: you're telling the compiler to import something that you're also defining locally.
This usually happens due to incorrect preprocessor macro usage, where the same header file is used for both building the DLL itself and for consuming the DLL, but the macros controlling dllexport
vs. dllimport
are not set up correctly for the current build context.
Common Solutions and Best Practices
The standard approach to manage dllexport
and dllimport
is to use preprocessor macros. This allows the same header file to serve both the DLL's internal compilation and external client usage without modification.
Here's a typical pattern:
- Define a macro (e.g.,
MYLIB_EXPORT
) that expands to__declspec(dllexport)
when building the DLL and__declspec(dllimport)
when consuming it. - Use a project-specific define (e.g.,
MYLIB_EXPORTS
) that is only defined when compiling the DLL project. - Apply the macro to all classes, functions, and variables that you intend to export from your DLL.
#ifndef MYLIB_GLOBAL_H
#define MYLIB_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(MYLIB_EXPORTS)
# define MYLIB_EXPORT Q_DECL_EXPORT
#else
# define MYLIB_EXPORT Q_DECL_IMPORT
#endif
#endif // MYLIB_GLOBAL_H
Example of a global header for DLL export/import management (e.g., mylib_global.h
)
In Qt projects, Q_DECL_EXPORT
and Q_DECL_IMPORT
are convenient macros provided by Qt that abstract away the platform-specific __declspec
keywords (and handle GCC's __attribute__((visibility("default")))
for Linux/macOS). This makes your code more portable.
Then, in your class or function declarations:
// mylib.h
#include "mylib_global.h"
class MYLIB_EXPORT MyClass {
public:
MyClass();
void doSomething();
};
MYLIB_EXPORT void myFunction();
Applying the MYLIB_EXPORT
macro to a class and a function
MYLIB_EXPORTS
(or your chosen macro) is defined only in the project settings of the DLL you are building. For client projects that link against this DLL, this macro should not be defined.graph TD A[Start Build Process] A --> B{Is current project building the DLL?} B -- Yes --> C[Define MYLIB_EXPORTS] B -- No --> D[Do NOT define MYLIB_EXPORTS] C --> E[Compile DLL Source Files] D --> F[Compile Client Source Files] E --> G[DLL Output (.dll, .lib)] F --> H[Client Executable/DLL] G -- Link against --> H
Decision flow for defining MYLIB_EXPORTS
during compilation
1. Step 1: Create a Global Export Header
Create a header file (e.g., yourlib_global.h
) that defines your export macro using Q_DECL_EXPORT
and Q_DECL_IMPORT
based on a preprocessor symbol (e.g., YOURLIB_EXPORTS
).
2. Step 2: Apply the Macro to Your DLL's Public API
Prefix all classes, functions, and global variables that you want to expose from your DLL with the newly defined export macro in their declarations within your DLL's public header files.
3. Step 3: Configure Project Settings
In your DLL project's build settings (e.g., .pro
file in Qt Creator, or Visual Studio project properties), add YOURLIB_EXPORTS
to the preprocessor definitions. Ensure this define is not present in any client projects that consume the DLL.
4. Step 4: Rebuild Your Projects
Clean and rebuild both your DLL project and any client projects that use it. This ensures all files are compiled with the correct dllimport
/dllexport
settings.
dllexport
to template instantiations unless you explicitly intend to export specific instantiations. Templates are typically instantiated by the compiler where they are used, and exporting them can lead to complex issues or larger DLLs.