【问题标题】:Dll Memory ManagementDLL内存管理
【发布时间】:2011-05-01 04:22:58
【问题描述】:

我对 windows 如何管理 .dll 的内存毫无疑问。

  • .dll 加载到主机时 进程,内存是如何管理的?

  • .dll 是否可以访问整个 主机进程可用的内存 还是只是其中的一部分?即是 内存是有限制的 由内部的函数分配 .dll?

  • 将 STL 类如字符串、向量(动态 增加存储)等由 dll,在这里可以正常工作吗?

【问题讨论】:

标签: c++ c dll memory-management


【解决方案1】:

“内存管理”通常是一种分担责任。操作系统将大块地址空间交给运行时,然后运行时将其以较小的位分配给程序。该地址空间可能分配了 RAM,也可能没有分配。 (如果没有,会有交换空间支持它)

基本上,当加载 DLL 时,Windows 会为代码和数据段分配地址空间,并调用DllMain()。 C++ 编译器将安排从DllMain() 调用全局ctor。如果它是用 C++ 编写的 DLL,它可能依赖于 C++ 运行时 DLL,而后者又依赖于 Kernel32.DLL 和 User32.DLL。 Windows 了解此类依赖关系,并将安排它们以正确的顺序加载。

证明只有一个地址空间,因此 DLL 将访问进程的所有内存。如果在两个进程中加载​​一个 DLL,则代码和数据将有两个逻辑副本。 (不过,代码和只读数据的副本可能共享相同的物理 RAM)。

如果 DLL 使用操作系统函数分配内存,Windows 会将内存分配给 DLL 从中进行分配的进程。进程必须返回内存,但进程中的任何代码都可以这样做。如果您的 DLL 使用 C++ 函数分配内存,它将通过在 C++ 运行时 DLL 中调用 operator new 来完成。该内存必须通过在(相同的)C++ 运行时 DLL 中调用 operator delete 来返回。同样,谁做这件事并不重要。

vector<> 这样的STL 类可以多次实例化,但只要您使用相同的编译器就没有关系。所有实例化将基本相等,并且都将向量的内存返回给相同的释放函数。

这个解释有两个主要假设:

  1. EXE 和它的 DLL 都是用同一个编译器编译的
  2. EXE 及其 DLL 都链接到 C++ 运行时 DLL(即非静态链接)

如果您想发布一个独立的 EXE,则针对 C++ 运行时的静态链接非常有用。但是,如果您已经发布了 DLL,那么您也应该将 C++ 运行时保存在自己的 DLL 中。

【讨论】:

  • 像vector这样的STL类可以多次实例化,但只要你使用相同的编译器就没有关系。 -- 应该补充一点不仅应该是相同的编译器,而且应该是相同的标志(如果有的话):_SECURE_SCL 等。
【解决方案2】:

.dll 是否可以访问整个 主机进程可用的内存 还是只是其中的一部分?即在那里 分配内存时的限制 通过 .dll 中的函数?

在将 DLL 加载到宿主进程后,DLL 中“活动”的 代码 与原始可执行模块中“活动”的代码没有任何区别。对于正在执行的进程,所有内存范围都是相同的,无论它们来自 DLL 还是来自原始可执行文件。

DLL 中的代码可以做什么与原始 exec 模块中编译的代码可以做什么没有区别。

也就是说,使用堆时存在差异 - 这些问题在 Space_C0wb0y 提供的问题中进行了解释,该问题在 comments 中提供了链接

将 STL 类如字符串、向量 (动态增加存储)等 由 dll 使用,工作没有问题 在这里?

如果您在 DLL 的接口中使用它们,它们产生问题(可解决的问题,但仍然存在)。如果您不在 DLL 接口级别使用它们,不会(或仅在极少数情况下)会产生问题。我相信还有一些更具体的问题+答案。

基本上,如果您在接口级别使用它们,则 DLL 和 EXE 必须使用“完全相同”的标志进行编译,即类型需要是二进制兼容的。 IE。如果您的 DLL 中的编译器标志(优化等)与 EXE 中的不同,以至于std::string 在 EXE 与 DLL 的内存中的布局不同,则在两者之间传递一个字符串对象将导致在崩溃或无声错误(或恶魔飞出你的鼻子)。

如果您只在函数内部或 DLL 内部函数之间使用 STL 类型,那么它们与 EXE 的兼容性无关紧要。

【讨论】:

  • “如果您在 DLL 的接口中使用它们,它们会产生问题(可解决的问题,但仍然存在)” - 您能解释更多或举个例子吗?
猜你喜欢
  • 2011-01-16
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-06
  • 2011-07-21
  • 2012-03-21
相关资源
最近更新 更多