Iban
Iban

Reputation: 149

Use #ifdef in .lib and defining variable in linkin project

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

Answers (2)

James Kanze
James Kanze

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 ifs 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

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

Related Questions