【问题标题】:In C/C++, how do I determine if a library is statically linked or not在 C/C++ 中,如何确定库是否为静态链接
【发布时间】:2021-05-04 09:43:23
【问题描述】:

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

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

我希望能够通过将此库的 GUI 功能分离到提供 GUI 支持的单独“扩展”库中来改进/简化问题。我的计划是在运行时主库以某种方式检测到 GUI 支持库的存在。如果存在,则它从提供必要功能的 GUI 库中实例化一个对象,如果不存在,它从自身实例化一个对象,该对象提供与“存根”函数相同的 API,这些函数什么都不做或适当地返回错误。这两个对象将继承自一个通用的纯虚拟抽象基类。

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

我一直在考虑在主库中实现这样的函数:

bool SupportsGUI() { return false; }

然后在 GUI 支持库中实现相同的功能,如下所示:

bool SupportsGUI() { return true; }

然后,在链接应用程序时,以某种方式强制链接器解析链接以使用 GUI 支持库中的链接(如果存在)。

我不知道如何让它工作。

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

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

【问题讨论】:

  • 您想要一个具有默认行为的类,在加载某个动态库时表现不同?
  • ...或者您是否希望根据您内置的静态库改变行为?
  • 为什么要关心在运行时在构建时链接了哪个库?到可执行文件运行时,静态库不再作为实体存在。那么在 CLI 和 GUI 版本中构建静态差异的真正问题是什么?强制客户端同时链接 -lalastair -lalastair_gui 而不仅仅是 -lalastair 并没有任何明显的好处。
  • @Yunnosch...是的。
  • @Useless 因为我想将 GUI 代码与功能代码分开。我想要一个库的单一版本,我可以在任何地方使用 option 还包括 GUI 功能。这个特定的库支持 Qt 和 MFC(不是同时),以及非 GUI CLI 版本。我被#defines 和一个非常复杂的 CMakeLists.txt 杀死了。

标签: c++ c


【解决方案1】:

这确实需要在运行时完成。常见的解决方案是使用弱符号。这是库中的一个符号,当没有“正常”符号可链接时使用。您的基础库提供弱符号,您的 GUI 库可选地提供替换,静态链接器会计算出来。

【讨论】:

    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • 这不是一个坏主意,但我真的很想使用静态链接。应用程序将使用或不使用 GUI。这没有条件。使用插件机制,DLL 需要单独管理,包含在安装程序中等等。如果它丢失或意外删除,那么 GUI 应用程序将在没有任何明显原因的情况下中断。还有其他与共享的公共库行为有关的问题。
    猜你喜欢
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 2023-01-18
    • 1970-01-01
    • 2010-11-14
    相关资源
    最近更新 更多