So the common (at least VS 2005 states) way to define exports/imports for a DLL is:
#ifdef MY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
class MY_API MyClass {
...
};
This works great if I'm just building my code as a DLL. However, I want to have the option of using a static library OR a DLL. Now one obvious (but terrible) solution, is to copy all the code, removing the DLL 'MY_API' defines. Now what would seem a much better approach is a command line switch to either define, or not define the DLL stuff. However in the case of a static library what should 'MY_API' be?
#ifdef DLL_CONFIG
#ifdef MY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
#else
#define MY_API // What goes here?
#endif
class MY_API MyClass {
...
};
Now assuming that this can be done will there be issues when a user of the library includes the header files (ie. will they have to define 'DLL_CONFIG')?
All you need to do in order to use such library (either in .exe or . dll ) is to include proper headers and link them - with Visual Studio it's pretty easy. First of all, you need to know 1) where your static libraries are placed and 2) their exact names. Go to project properties and then General .
Yes, the Core and Utils code will be duplicated. Instead of building them as static libs you can build them as dlls and use anywhere. Save this answer.
No. A library contains solely and only object files. Headers are not object files. Headers are not contained in libraries.
What are the differences between static and dynamic libraries? Static libraries, while reusable in multiple programs, are locked into a program at compile time. Dynamic, or shared libraries, on the other hand, exist as separate files outside of the executable file.
Nothing.
Leave it as #define MY_API
and all instances of MY_API will simply vanish.
You can add new build configurations, such as Debug - DLL and Release - DLL that mimic the others except they #define DLL_CONFIG
.
To clone a configuration, get to the configuration manager (like the drop down of the Debug/Release list box), then under 'Active solution configuration' select new. You can now name it "Debug - DLL" and set Copy Settings
to Debug
and now that's left to do is define DLL_CONFIG
.
To do this, go to project properties->configuration properties->C/C++->Preprocessor, and type DLL_CONFIG
in there. You will also see that's where things like NDEBUG
and WIN32
are defined.
Like haffax said, use project specific names. I would recommend something like:
#ifdef THEPROJECT_USE_DLL
#ifdef THEPROJECT_BUILDING_PROJECT
#define THEPROJECT_API __declspec(dllexport)
#else
#define THEPROJECT_API __declspec(dllimport)
#endif
#else
#define THEPROJECT_API
#endif
Now users of your DLL just #define THEPROJECT_USE_DLL
if they are using the DLL version, just like your "- DLL" configurations have.
Just define MY_API as empty. Like this:
#ifdef DLL_CONFIG
#ifdef MY_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
#else
#define MY_API
#endif
In case of static linking no declspec is necessary.
Users of your library will have to define DLL_CONFIG
if they want to use it as a dll or not define it if they want to use it as a static library.
There won't be any issues as is. This kind of configuration is done in many libraries.
Edit: Of course you shouldn't use the names MY_EXPORTS
and DLL_CONFIG
as such. Use project specific prefixes for all of your macros, so that there are no name clashes.
Do nothing. No special calling convention is needed to link against a static library. The only thing you need to do, is to make sure that the linker links with your.lib.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With