将EXE数据向下传递到一个或者多个DLL

时间:2020-03-05 18:59:12  来源:igfitidea点击:

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

为了减轻EXE的占用空间并支持我们进行配置管理,我们决定将页面分成一个单独的DLL,供EXE加载。我们的目的是让EXE成为将DLL中的页面加载到其中的外壳。 EXE仍将具有所有通信职责(UDP,Corba,用户等)。这些页面仍将负责显示其所做的一切。

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

  • 将当前存储在单独的单例中的所有数据包装到另一个DLL中,该DLL将导出"真实"的单例。例如。从DLL导出的单例将是相同的-不管是什么EXE加载它-就像共享内存一样。这是一个有趣的选择,但会在我们的部署方案中引起问题。如果人们真的被这个想法迷住了,我可以详细介绍这些问题。
  • 创建一个包含所有相关数据的静态DLL级别结构。 EXE将在DLL加载后将此数据下推到DLL,以便DLL中包含的页面可以访问该数据。这似乎是最简单的解决方案-即使它需要编辑应用程序中的每个页面-超过100个。看起来也有些草率。所有数据都只是全局的。也不太性感或者C ++ y。

那么,还有其他人对此问题有解决方案吗?

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

解决方案

回答

我们可以:

  • 将所有东西从最外面的外壳放入一个"通用" DLL;
  • 使用DEF文件从EXE生成导出功能。

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

回答

不幸的是,听起来我们已经有很多现有的代码需要修改。在这种情况下,我只想使用(2),并假设它不会变得太大和笨拙。

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

如果(2)太凌乱,我将对其进行一些重构,以使其具有带有Seri​​alize / UnSerialize()函数的基本" DLLPage"类。永远不要导出类本身,而只导出其中需要的单个功能(这在类更改时会非常有帮助……在类级导出中发生非常奇怪的中断)。我们将需要构造函数/析构函数,并且可能需要每个公共成员。

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

回答

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

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

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

回答

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

回答

第一种选择:将exe拥有的所有数据放入共享内存中。只要我们有适当的锁定位置,这些dll便可以愉快地访问它。

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

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