【问题标题】:Boost log and dynamically loaded librariesBoost 日志和动态加载的库
【发布时间】:2020-10-27 09:22:22
【问题描述】:

我们在适用于 Windows 和 Linux 的应用程序中使用 Boost.Log v2 (1.70)。最近我重构了一个动态加载的 dll 以使用 Boost.Log。

dll 导出 C api 函数以访问专用硬件。它用于各种编程环境:C、C++、Python、Delphi 和 Labview。 (他们中的大多数不使用 Boost.Log)。

对于 Windows,构建的 dll 仅使用静态库并使用静态运行时,使部署更加容易。

这按预期工作:两个 boost 日志实例似乎完全相互独立。 应用程序登录到它的文件接收器,dll 进入另一个接收器。

在 Linux 上,插件被构建为使用共享运行时和共享 boost 库。我们故意这样做是为了能够使用 Linux 发行版的 boost 库。

效果是插件加载后应用程序不再登录到它的接收器。我们看到的是来自插件的日志。 由于 api dll 不知道可能还有其他人也在使用 Boost.Log(== 相同的实例),因此它在重新配置日志记录时调用 boost::log::core::get()-> remove_all_sinks()。

是否可以走类似的路线(如在 Windows 中)并尝试使用静态链接和静态运行时构建插件?

或者这种方法注定要失败?

虽然目前可以工作,但是否使用静态运行时 + 静态链接 Boost.Log 是适用于 Windows 的可行构建配置?

提前致谢, 冈瑟

【问题讨论】:

  • 你有全局变量(全局可变状态,可能伪装成单例),现在你为它付费。我建议您重构代码以将所需的实例注入您的类(依赖注入或依赖反转)以重新获得控制权。

标签: c++ boost-log


【解决方案1】:

在多个模块(可执行和/或共享库)中使用 Boost.Log 的静态库是 not supported 并且不会按预期工作。 Boost.Log 在内部维护了许多单例,但在一个进程中拥有多个 Boost.Log 实例会破坏这些单例。

【讨论】:

    【解决方案2】:

    感谢 Andrey Semashev 和 Ulrich Eckhardt。

    我现在了解到 Boost.Log 的库实现限制了它的使用。

    无效用法:应用程序链接 boost 日志(作为 dll)并通过使用 dlopen(Linux) 或 LoadLibrary(Windows ) 是未定义的行为。它可能有效,也可能无效。

    有效用法:如果两个工件(app、api.dll)共享 Boost.Log(通过 dll、共享运行时),他们必须意识到这一点,以便一个工件的日志记录配置不会被另一个更改或删除。从技术角度来看,这仍然是一个有效的用例。

    以后我们将不再在 api.dll 中使用 Boost.log 来消除这种情况下的未定义行为。

    @Ulrich Eckhard:Api.dll 的接口仅是 C。这是需要的,因为 Api 用于各种环境(C、C++、Python、Labview 等)。这就是为什么 api.dll 带有自己完整的日志基础设施的原因。没有暴露类 - 在这种情况下,依赖倒置不是一个可行的解决方案。

    谢谢,

    冈瑟

    【讨论】:

      猜你喜欢
      • 2011-08-14
      • 2023-03-14
      • 2015-10-07
      • 2013-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多