所以我正在为我和我的团队开发Modular C ++库。这是我的情况:
我有一个库A
,其中包含一个复杂的存储控件class a
。我还有一个库B
,它类似于包含特殊响应的复杂协议的接口。现在,我希望在类a中有一个函数,可以使用B
。这对使用X
和A
的计划B
很有帮助。但也有计划Y
,它只会使用A
,而不会使用复杂的库B
。
如何在C ++中获得此行为?我是否需要宏,符号或是否有其他方法可以轻松实现这一点,以便我不需要在程序中包含额外的文件?哪种类型的库更好?
答案 0 :(得分:5)
这在系统库中非常常见,可以在(库)编译时选择可选功能。使用此方法,您将拥有一个或多个#define
预处理器宏来保护可选功能。因此,在图书馆A:
#ifdef USE_LIBRARY_B
#include <b/foo.h>
int A_optional_feature_using_B(void) { ... }
#endif
// rest of library A follows
在编译时,您可以定义USE_LIBRARY_B
或不定义(当然也可以添加任何必要的链接器标志)。例如,在类似UNIX的平台上使用gcc
:
$ gcc ... -DUSE_LIBRARY_B ...
最常见的是,autoconf
之类的东西用于UNIX环境,为最终用户提供了一种选择可选功能的简便方法。因此,您可能会看到:
me@pc:library_a$ ./configure --with-library-b
有关如何设置类似内容的信息,请参阅autoconf
文档。
在Windows上,您可以执行类似的操作(例如,在Visual Studio中,使用定义相应宏的不同Project / Solution配置)。
以上为您提供仅编译时对额外功能的控制。要允许在运行时中进行选择,以便库可以使用B(如果存在),则需要使用运行时动态链接。这是高度特定于平台的。在Linux上,使用libdl
。在Windows上,使用LoadLibrary()
和朋友。在这里,您将需要执行大量额外编码以查找并加载可选库(如果存在)并返回相应的错误代码/异常(如果不存在)以及需要可选库的函数。
如果所有这些听起来像是后方的痛苦,那么你是对的,它就是。如果有任何合理的方法来调整您的策略,以便您不必这样做,那么您将会变得更好。但是对于某些用例,这个是必要且适当的,如果你的是,那么我希望上面给你一些起点,祝你好运。