Search code examples
c++class

Two libraries which can expand each other


So I'm working on an Modular C++ library for me and my team. Here is my situation:

I have a library A which contains a complex storage control class a. I have also a library B that is something like a interface to an complex protocol which contains an special response. Now, I want to have a function in class a, which CAN use B. This can be helpful for Program X, which uses A and B. But there is also Program Y, which will only use A and not the complex library B.

How can I get this behavior in C++? Do I need macros, symbols or is there an other way to implement this easily so that I don't need to include an extra file in a Program? Which type of library is the better one?


Solution

  • This is pretty common in system libraries, where optional features can be chosen at (library) compile time. With this approach, you would have one or more #define preprocessor macros guarding the optional features. Thus, in library A:

    #ifdef USE_LIBRARY_B
    #include <b/foo.h>
    int A_optional_feature_using_B(void) { ... }
    #endif
    
    // rest of library A follows
    

    At compile time you would either define USE_LIBRARY_B or not (and add any necessary linker flags of course). For example, with gcc on a UNIX-like platform:

    $ gcc ... -DUSE_LIBRARY_B ...
    

    Most commonly, something like autoconf is used for UNIX environments to give the end-user an easy way to select the optional features. Thus, you might see:

    me@pc:library_a$ ./configure --with-library-b
    

    See the autoconf documentation for information on how to set something like that up.

    On Windows, you could do something similar (e.g., in Visual Studio, use different Project/Solution configurations that define the appropriate macros).


    The above gives you compile-time only control over the extra features. To allow the choice to be made at runtime so that the library can use B if present, you will need to use runtime dynamic linking. This is highly platform-specific. On Linux, use libdl. On Windows, use LoadLibrary() and friends. Here you will have to do a lot of extra coding to look for and load the optional library if present and to return appropriate error codes / exceptions if not present and functions requiring the optional library are called.


    If all this sounds like a pain in the rear, you're right, it is. If there is any reasonable way to adjust your strategy so that you don't have to do this, you will be better off. But for some use cases this is necessary and appropriate and if yours is so, then I hope the above gives you some starting points, and good luck.