Boost日志和动态加载的库

Boost log and dynamically loaded libraries

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

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

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

这按预期工作:两个提升日志实例似乎完全独立于彼此。 该应用程序登录到其文件接收器,dll 登录到另一个文件接收器。

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

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

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

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

虽然目前有效,但使用静态运行时 + 静态链接 Boost.Log 是 Windows 的可行构建配置吗?

提前致谢, 冈瑟

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

谢谢 Andrey Semashev 和 Ulrich Eckhardt。

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

无效用法: 一个应用程序链接 boost 日志(作为 dll)并使用 dlopen 动态加载另一个 api.dll(静态链接以通过静态运行时静态提升日志) (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 带有自己完整的日志基础结构的原因。没有 类 暴露 - 在这种情况下依赖倒置不是可行的解决方案。

谢谢,

冈瑟