我有一个提供一些功能的静态库。我有使用这个库的应用程序。其中一些应用程序是命令行应用程序或作为守护程序/服务运行。其中一些应用程序是 GUI 应用程序。
该库提供了提供 GUI 元素的功能,以允许用户对其进行配置。我以两种风格构建图书馆:GUI 风格和 CLI 风格。然后我将适当的版本链接到应用程序。
我希望能够通过将该库的 GUI 功能分离到提供 GUI 支持的单独“扩展”库中来改进/简化问题。我的计划是在运行时主库以某种方式检测 GUI 支持库的存在。如果存在,则它会实例化 GUI 库中提供必要功能的对象,如果不存在,它会实例化自身的对象,该对象提供与“存根”函数相同的 API,这些函数不执行任何操作或根据需要返回错误。这两个对象将从一个共同的纯虚拟抽象基类继承。
这必须在运行时完成,因为我希望能够将主库的完全相同的二进制文件链接到 CLI 和 GUI 应用程序,而不是依赖于编译时开关,根据定义,编译时开关会导致不同的二进制文件。
我一直在考虑在主库中实现这样的函数:
bool SupportsGUI() { return false; }
Run Code Online (Sandbox Code Playgroud)
然后在 GUI 支持库中实现相同的功能,如下所示:
bool SupportsGUI() { return true; }
Run Code Online (Sandbox Code Playgroud)
然后,在链接应用程序时,以某种方式强制链接器解析链接以使用 GUI 支持库(如果存在)中的链接。
我不知道如何让它发挥作用。
假设两个库都是静态库,我如何在运行时从一个库确定链接应用程序是否也链接了另一个库?
或者,如何在链接时用在单独的库中实现的一组等效函数覆盖在一个库中实现的一组函数。
这不需要在运行时完成。常见的解决方案是使用弱符号。这是库中没有“正常”符号可链接时使用的符号。你的基础库提供了弱符号,你的 GUI 库可以选择提供替换符号,静态链接器会计算出来。