C++ 在C/C++;,如何确定库是否静态链接

C++ 在C/C++;,如何确定库是否静态链接,c++,c,C++,C,我有一个提供一些功能的静态库。我有使用此库的应用程序。其中一些应用程序是命令行应用程序或作为守护进程/服务运行。其中一些应用程序是GUI应用程序 该库提供了提供GUI元素的功能,允许用户对其进行配置。我用两种风格建造图书馆;GUI风格和CLI风格。然后将适当的版本链接到应用程序 我希望能够通过将该库的GUI功能分离为一个单独的“扩展”库来改进/简化问题,该库提供GUI支持。我的计划是,在运行时,主库以某种方式检测GUI支持库的存在。如果存在,则从GUI库实例化一个提供必要功能的对象;如果不存在,

我有一个提供一些功能的静态库。我有使用此库的应用程序。其中一些应用程序是命令行应用程序或作为守护进程/服务运行。其中一些应用程序是GUI应用程序

该库提供了提供GUI元素的功能,允许用户对其进行配置。我用两种风格建造图书馆;GUI风格和CLI风格。然后将适当的版本链接到应用程序

我希望能够通过将该库的GUI功能分离为一个单独的“扩展”库来改进/简化问题,该库提供GUI支持。我的计划是,在运行时,主库以某种方式检测GUI支持库的存在。如果存在,则从GUI库实例化一个提供必要功能的对象;如果不存在,则从自身实例化一个对象,该对象提供与“存根”函数相同的API,这些函数不执行任何操作或根据需要返回错误。这两个对象将从一个公共的纯虚拟抽象基类继承

这必须在运行时完成,因为我希望能够将主库的完全相同的二进制文件链接到CLI和GUI应用程序,而不依赖编译时开关,根据定义,编译时开关会导致不同的二进制文件

我一直在考虑在主库中实现如下函数:

bool SupportsGUI() { return false; }
bool SupportsGUI() { return true; }
然后在GUI支持库中实现相同的功能,如下所示:

bool SupportsGUI() { return false; }
bool SupportsGUI() { return true; }
然后,在链接应用程序时,以某种方式强制链接器解析链接,以使用GUI支持库中的链接(如果存在)

我想不出怎么让它工作

假设两个库都是静态库,我如何在运行时从一个库确定链接应用程序是否也链接了另一个库


或者,在链接时,我如何用在单独库中实现的一组等效函数覆盖在一个库中实现的一组函数。

为此,您需要一个插件加载系统

  • 插件API库定义了接口(例如,一个抽象类定义了一些您希望能够调用的虚拟函数)

  • 插件实现了实际的GUI代码。这是一个在运行时加载的共享库,具有硬编码路径和某种形式的可配置或固定路径/文件名。其他插件或应用程序本身实现了在硬编码插件时使用的回退实现

  • 然后,应用程序尝试加载GUI插件,并从动态加载的库中调用特定函数来创建GUI特定插件对象。如果插件无法加载,它将实例化回退对象


  • 有许多帮助程序库可用于执行此类操作。Qt有一个
    QPluginLoader
    类,但是还有其他各种半通用包装器来加载动态库并从中实例化插件接口。

    这不需要作为运行时来完成。常见的解决方案是使用弱符号。这是库中的一个符号,在没有“正常”符号可链接时使用。您的基本库提供弱符号,您的GUI库可选地提供替换,并且静态链接器可以解决此问题。

    您想要一个具有默认行为的类,该类在加载某个动态库时的行为会有所不同吗?。。。或者,您希望行为根据您构建的静态库而改变吗?为什么在运行时关心构建时链接了哪个库?在可执行文件运行时,静态库不再作为实体存在。那么,在CLI和GUI版本中构建静态差异的真正问题是什么?强制客户端链接两个
    -lalastair-lalastair\u gui
    而不是只链接
    -lalastair
    没有任何明显的好处。@Yunnosch…Yes。@没有用,因为我想将gui代码与功能代码分开。我希望有一个库的单一构建,我可以在任何地方使用它,还可以选择包括GUI功能。这个特定的库支持Qt和MFC(不是同时支持),以及非GUI CLI版本。我被#defines和一个非常复杂的CMakeLists.txt扼杀了。这不是个坏主意,但我真的想使用静态链接。应用程序将使用或不使用GUI。这是没有条件的。使用插件机制,DLL需要单独管理,包括在安装程序中,等等。如果它丢失或意外删除,GUI应用程序将在没有任何明显原因的情况下崩溃。还有其他与共享公共库行为有关的问题。