Reputation: 149
I am creating a library (.lib) in c++ with Visual Studio 2008. I would like to set a variable to change the behaviour of the library depending on the variable. Simplifying a lot, something like this:
#ifdef OPTION1
i = 1;
#else
i = 0;
#endif
But the variable (in this case OPTION1) should not be defined in the library itself, but in the code that links to the library, so that just changing the definition of the variable I could obtain different behaviours from the program, but always linking to the same library.
Is this possible, and how? Or is there a more elegant way to achieve what I want?
Upvotes: 1
Views: 472
Reputation: 154007
The simple answer is no. Things like #ifdef
are entirely
processed by the compiler (and in fact, by a preprocessor phase
of the compiler, before it even parses the code); a .lib
file
has already been compiled.
One solution would be to supply the library in source form, and let the client compile it as part of his project. This has an additional advantage in that you automatically support all versions of the compiler, with all possible combinations of compiler options. And the disadvantage that your library will be used with versions of the compiler and compiler options that you've never tested, and that possibly you cannot even test.
Otherwise, you'll need to use a variable, and if
s and ?:
,
rather than #ifdef
. And you'll have to arrange some means of
setting the variable.
Finally, if there's only one such variable, you might consider
furnishing two different sets of versions of the library: one
with it set, and one without. The client then decides which one
he wants to use. In many ways, this is the simplest solution,
but it definitely doesn't scale—with a hundred such
variables, if they're independent, you'll need 2^100
different
sets of variants, and that won't fit on any disk.
Upvotes: 1
Reputation: 171167
To pull this off, the code which depends on the macro must be compiled as part of the code which links to the library, not as part of the library itself. The best you could do is something like this:
In your public .h file:
namespace LibraryPrivate {
void functionForOptionSet();
void functionForOptionUnset();
}
#ifdef OPTION1
inline void dependentBehaviour() {
LibraryPrivate::functionForOptionSet();
}
#else
inline void dependentBehaviour() {
LibraryPrivate::functionForOptionUnset();
}
#endif
In you library's .cpp file:
namespace LibraryPrivate {
void functionForOptionSet()
{ i = 1; }
void functionForOptionUnset()
{ i = 0; }
}
That is, you have to implement both options in the library, but you can (partially) limit the interface based on the macro. Kind of something like what WinAPI does with char
vs. wchar_t
functions: if provides both SomeFunctionA(char*)
and SomeFunctionW(wchar_t*)
and then a macro SomeFunction
which expands to one of those.
Upvotes: 1