To be clear:
I'm aware that the below example demonstrates a dll-dependancy, i.e. one library is not self-containe, but depends on another library to function.
Let's say I'm creating a runtime library, Utility.dll, which contains various useful functions of general nature.
I create a header file Utility.h to be included in other files which need to use Utility.dll.
The header file looks like
#ifndef _UTILITY_H
#define _UTILITY_H
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
DLL_EXPORT void foo();
DLL_EXPORT void foo2();
....
#endif
When I compile the source code file Utility.cpp into machine code (into Utility.dll) I make sure BUILD_DLL is defined so DLL_EXPORT gets replaced with __declspec(dllexport). This makes the functions be exported to the .dll file.
Whenever I include the header Utility.h and link with the import library (Utility.lib for MS VS, libUtility.a for g++) and do not define BUILD_DLL, the function declarations in Utility.h begin with __declspec(dllimport) instead, telling the compiler that the functions are imported from a .dll (so to speak).
Now, let's say I'm also building another library, MyLibrary.dll, which wants to use some of the useful functions in Utility.dll. Similarily, I would create MyLibrary.h as
#ifndef _MYLIBRARY_H
#define _MYLIBRARY_H
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
DLL_EXPORT void myLibraryFunc1();
....
#endif
When I compile MyLibrary.cpp into MyLibrary.dll I'm including Utility.h and also linking against the Utility import library.
This leads us to my question:
Since I define BUILD_DLL also when I compile MyLibrary.dll, this means that the function declarations in Utility.h also will read
__declspec(dllexport) void foo();
__declspec(dllexport) void foo2();
....
Not
__declspec(dllimport) void foo();
__declspec(dllimport) void foo2();
Don't we want it to be __declspec(dllimport) for the function declarations in Utility.h when we compile MyLibrary.dll, and __declspec(dllexport) for the function declarations in MyLibrary.h?
This is precisely the reason why you normally don't name such macros BUILD_DLL, but BUILD_UTILITY and BUILD_MYLIBRARY or similar. Likewise, the declspec macro should not be DLL_EXPORT, but UTILITY_EXPORT and MYLIBRARY_EXPORT (or perhaps UTILITY_API and MYLIBRARY_API).
Related
I have Math.h and Math.lib. How I create dynamic link library from this files?
You can create project for Dynamic Link Library (DLL) and add Math.lib as input library in project properties. Also you classes in Math.h should be exported (use __declspec(dllexport) and __declspec(dllimport) for that).
#pragma once
#ifdef MATH_DLL
#define EXPORT_CLASS __declspec(dllexport)
#else
#define EXPORT_CLASS __declspec(dllimport)
#endif
class EXPORT_CLASS Math {
public:
Math( double y );
int DoSomething( int x );
};
Macro MATH_DLL should be defined in preprocessor definitions in project properties.
Hi I'm little bit confused with dllexport.When I use __declspec( dllexport ) for example in class
#define DllExport __declspec( dllexport )
class DllExport C {
int i;
virtual int func( void ) { return 1; }
};
do I export class C to dll file or do I export C class from dll file?
When compiling the DLL you have to write __declspec(dllexport) as you did. This tells the compiler you want it to be exported. When using the DLL you want __declspec(dllimport) in your included files. The compiler then knows that this functions and classes are in a DLL-file and need to be imported. Because you don't want to change your header-files that much, you should define a macro e.g. BUILD_DLL.
#ifdef BUILD_DLL
#define DLL_PORTING __declspec(dllexport)
#else
#define DLL_PORTING __declspec(dllimport)
#endif
Now you write in example.h:
class DLL_PORTING example_class { … };
In your .exe file just include the header files you need and everything will work.
I have a class which header looks like this:
class MYCLASS_DECLSPEC MyClass
{
MyClass(int x);
....
static const MyClass Zero;
}
On the implementation file I initialized the static const member:
const A A::Zero(0);
Now I want to compile this code sometimes as a DLL and sometimes as static library. The common practice is to define MYCLASS_DECLSPEC like this:
#ifdef BUILDING_MYDLL
#define MYCLASS_DECLSPEC __declspec(dllexport)
#else
#define MYCLASS_DECLSPEC __declspec(dllimport)
#endif
When I compile this code as DLL (with BUILDING_MYDLL defined) everything is working fine. But when I compile this code as static library (without BUILDING_MYDLL defined) I get the following error:
error: definition of static data member 'MyClass::Zero' of dllimport'd class
If I totally remove the __declspec(dllimport) the code compiles successfully as a static library.
I'm using mingw32 compiler on Windows 7.
Can someone explain why it happens and how to solve it?
I would think we put #defines in another #define:
#ifdef _DLL
#ifdef BUILDING_MYDLL
#define MYCLASS_DECLSPEC __declspec(dllexport)
#else
#define MYCLASS_DECLSPEC __declspec(dllimport)
#endif
#else
#define MYCLASS_DECLSPEC
#endif
I am looking for a way to export from my C++ dll a function with two overloads.
This is my overloads on the .h file:
static __declspec(dllexport) int __stdcall TotalCost(char* a, double* b);
static __declspec(dllexport) int __stdcall TotalCost(char* a, double* b, double c);
my questions are:
is it possible to export overloads of a function??
how I can set in the file .def the EXPORT ??
Thanks in advance
Fabio
Yes, you can export overloads.
The classic way is to add the following macro definition to your library headers:
#ifdef MYLIB_EXPORTS
#define MYLIB_API __declspec(dllexport)
#else
#define MYLIB_API __declspec(dllimport)
#pragma comment(lib,"MYLIB.lib")
#endif
//...
Use the above macro in your interface files:
MYLIB_API int ComputeTotal(...
class MYLIB_API C_MyClass...
You will have to define MYLIB_EXPORTS in your DLL project settings (C++/Preprocessor Definitions).
Here is a reproducing example
// in a header from a dll
class Window{
public:
MSG _declspec(dllexport) *getMessage(); //compiles
MSG* _declspec(dllexport) getMessage(); //fails
}
Definitions are set in a .cpp file.
In the Application, I cant access the Member function, why ? I am access the function of course from a instance of Window like:
Window App;
func_with_parameters(param,App.getMessage(),0,0); // not found !
Ok, first off.
__declspec(dllexport) MSG* GetMessage();
Is the proper way the function definition should be.
Secondly, the __declspec(dllexport) will need to be __declspec(dllimport) in the header file of the project that consumes the dll or it will not import. That is usually handled via macros such as this.
#ifdef _WINDLL // Defined by Visual Studio when building a Dll
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
Third, it may be better to export at the class level instead of the function level e.g.
class __declspec(dllexport) Window
or with the macro
class DLL_API Window