c++ - 静态对象如何跨 DLL 和 Windows 二进制内存共享

标签 c++ memory memory-management dll

我遇到了一些关于 DLL 的设计问题,我目前处于您可能称之为维基百科的状态 DLL Hell问题如下:

我创建了一个系统,其中有多个模块实现为 DLL。这些在应用程序中使用,可以加载 DLL,但并非所有都需要。如果只完成数学之类的事情,它可以链接到“Utilities.dll”并使用它。 问题是,我有一个记录器/跟踪器。这会将所有内容记录到一个文件和一个调试控制台,调试控制台只是一个流输出。问题是如何处理多个 DLL 试图使用相同的日志类。看到日志类在这个“Utilities.dll”中,“DataManagers.dll”和其他 dll 之类的东西也想使用日志类功能。这包括登录到文件。我目前正在使用关键部分来确保不会发生写冲突,但看到关键部分是在用户模式下实现的,我必须在某些时候切换到互斥锁或类似的东西才能拥有内核模式对象。但是,在 DLL 内存中有多个日志类实例意味着如果我只使用关键部分,我会遇到一些严重的问题。

我似乎无法拼凑的是一种方法,所有 DLL 都能够使用相同的日志类实例,而不必一个接一个地链接到 Utilities.dll。我不想将 8 个 dll 加载到我的演示项目中,并让所有这 8 个都引用具有日志类的那个 dll,如果我需要更多类似日志类的东西,这将有点链式 react 。有没有办法正确地做到这一点?使用类的功能,在其他 DLL 中的 DLL 中使用静态函数,在 .exe Windows 二进制文件中使用相同的“静态”函数,从而不会在写入日志文件甚至调试控制台的输出流时发生冲突。

如果我完全错了并且试图做不可能的事情,请告诉我并帮助实现尽可能接近的目标。我知道在 DLL 中使用 Singleton 模式时会出现一些类似的问题,但这已通过

解决

到目前为止我尝试了什么:

  • 在初始化 DLL 的类时,为它们提供日志库的实例,但这违背了类具有所有静态成员的目的。

我也发现了这个问题,它很相似(甚至我的全局工具的库的名称也是如此......)但它没有回答我的问题并且有一些不同的方法以及从 09 年开始。 How to mimic the "multiple instances of global variables within the application" behaviour of a static library but using a DLL?

最佳答案

您的问题根本不是“DLL hell ”。

这是对 DLL 工作原理的基本理解。每个进程最多加载一次 DLL。因此,如果您的 DLL 被多个其他 DLL 使用,它仍然会在每个进程中存在一次。如果您的日志类对象在 DLL 中实现为单例(例如全局对象),那么每个进程都有一个对象。

然后应保护该对象免受进程内的并发使用。关键部分是进程本地的,非常适合它。您不需要互斥锁,因为两个进程各有自己的 Utilities.DLL 拷贝及其对象。

如果您的记录器记录到单个固定文件,您可能会遇到问题。在这种情况下,两个进程将尝试记录到同一个文件。这是一个设计问题,您无论如何都不想绕过它。将您的日志输出分开,因此请确保每个记录器写入一个唯一的日志文件。

关于c++ - 静态对象如何跨 DLL 和 Windows 二进制内存共享,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10693829/

相关文章:

c++ - 如何将项目从 boost::variant 移动到 multimap ?

c - 传递的参数更改值

ios - 释放 UIPageViewController 中未使用的页面

c++ - 使用 move 语义的初始化列表顺序中的未定义行为

c++ - 从 64 位整数秒数创建一个 boost::posix_time::ptime 对象

c++ - 编译器如何工作以及 Makefile 在前向声明的情况下发挥作用

java - 关闭 ByteArrayOutputStream 的最佳方法是什么?

memory - Hadoop-是否可以将任务内存限制设置为低于2GB

linux - 为什么malloc依赖mmap从某个阈值开始?

100字节内存分配失败