1

我们当前的应用程序是一个包含多个页面的单个 OpenGL EXE。EXE 负责访问通过 UDP 通过网络发送的数据。它累积数据并将其存储在许多单例结构中。EXE 中的各个页面访问单例结构以按照它们认为合适的方式处理数据。

为了减轻我们的 EXE 占用空间并支持我们在配置管理方面的尝试,我们决定将页面拆分为一个单独的 DLL,EXE 将加载该 DLL。我们的目的是让 EXE 成为加载 DLL 页面的 shell。EXE 仍将承担所有通信职责(UDP、Corba、用户等)。这些页面仍将负责显示它们所做的任何事情。

问题(最终)变成了:如何将这些从 EXE 收集的无数数据传递到基于 DLL 的消费页面。单例概念不再成立,因为我们使用的单例 (ACE_Singleton) 不允许这种级别的方向。我们可以整天将单例从 DLL 导出到消耗的 EXE,但我还没有弄清楚相反的情况。我想出了以下选项-我都不喜欢,所以我希望那里的人会有更好的选择:)

  1. 将当前存储在单独单例中的所有数据包装到另一个 DLL 中,该 DLL 将导出“真正的”单例。例如。从 DLL 导出的单例将是相同的 - 无论 EXE 加载了什么 - 有点像共享内存。这是一个有趣的选择,但会导致我们的部署方案出现问题。如果人们真的被这个想法迷住了,我可以详细讨论这些问题。
  2. 创建一个包含所有相关数据的静态 DLL 级结构。EXE 会在 DLL 加载时将此数据下推到 DLL,以便 DLL 中包含的页面可以访问数据。这似乎是最简单的解决方案——即使它需要编辑我们应用程序中的每一页——超过 100 个。它也似乎有点草率。所有数据都在一个全局范围内。也不是很性感或 C++y。

那么,还有其他人有解决这个问题的方法吗?

该应用程序使用 Visual C++ 9.0 (VisualStudio 2008) 编写,可在 Windows XP 上使用。出于某种原因,我们的实验室还不支持 Vista——即使我们的客户正在使用它。

4

5 回答 5

1

给所有的 DLL 一个函数 SetGlobalDataPointer(Singleton*)。您的 EXE 在调用任何其他 DLL 函数之前调用此函数。在 DLL 代码中,替换所有出现的单例。通过SingletonPtr->

于 2008-10-01T10:30:41.623 回答
0

在您尝试分解 EXE 之前,您应该阅读内存管理和 DLL。

这是一篇讨论 CRT 对象问题的文章,但同样的事情也适用于您自己的 C++ 对象。

跨 DLL 边界传递 CRT 对象的潜在错误

于 2008-09-17T16:07:47.847 回答
0

您可以:

  • 把除了最外层的所有东西都放到一个“通用”DLL中;
  • 使用 DEF 文件从您的 EXE 生成导出函数。

第二种非常少见,但可以仅从 DEF 文件生成导入库。使用 LIB /DEF 生成导入库。请参阅使用导入库和导出文件

于 2008-09-17T15:57:38.977 回答
0

不幸的是,听起来您有很多现有的代码需要修改。在那种情况下,我会选择(2),假设它不会变得太大和笨重。

根据您的描述,听起来 EXE 级别的数据只需要在 DLL 加载时发送一次。

如果 (2) 太混乱,我会对其进行一些重构,使其具有带有 Serialize/UnSerialize() 函数的基本“DLLPage”类。永远不要导出类本身,只导出你需要的单个函数(随着类的变化,这很有帮助......类级导出会发生非常奇怪的中断)。您将需要构造函数/析构函数,可能还需要每个公共成员。

可能存在一些堆管理问题,所以我也喜欢重载 new/delete 并让所有类使用位于帮助 DLL 中的集中式 new/delete。

于 2008-09-17T15:58:14.390 回答
0

第一个选项:将 exe 保存的所有数据放在共享内存中。只要您有适当的锁定,dll 就可以愉快地访问它。

第二种选择:使用导出的函数指针将内存转移到 dll - exe 有一个函数,dll 调用 exe 中的另一个函数,该函数将这个函数作为指针返回,然后 dll 可以调用该函数。该导出函数可以将数据作为堆栈上的正常结构传输。

第三个选项:如果您使用相同的运行时,只需导出一个指针,让您可以直接访问内存。

于 2009-01-13T19:04:31.397 回答