DLL内存管理

Sys*_*min 9 c c++ dll memory-management

我对Windows如何管理.dll的内存几乎没有疑问.

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

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

  • STL类如dll使用的字符串,向量(动态增加存储)等,在这里没有问题吗?

MSa*_*ers 6

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

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

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

如果DLL使用OS函数分配内存,Windows将把内存分配给DLL进行分配的进程.进程必须返回内存,但进程中的任何代码都可以这样做.如果你的DLL使用C++函数分配内存,它将通过调用operator newC++运行时DLL来实现.必须通过调用operator delete(相同的)C++运行时DLL 来返回该内存.同样,谁做到这一点并不重要.

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

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

  1. EXE及其DLL都使用相同的编译器进行编译
  2. EXE及其DLL都链接到C++运行时DLL(即不静态链接)

如果要发布单个自包含的EXE,则对C++运行时的静态链接很有用.但是,如果您已经加载了DLL,那么您应该将C++运行时保留在自己的DLL中.


Mar*_* Ba 5

.dll是否可以访问主机进程可用的全部内存或其中的一部分?即当.dll中的函数分配内存时有限制吗?

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

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

这就是说,有使用堆时的差异- Space_C0wb0y中提供的链接,这些都在说明问题的意见

dll使用的STL类(例如字符串,向量(动态增加存储空间)等)在这里可以正常工作吗?

如果您在DLL的界面中使用它们,它们创建问题(但可以解决)。该不会(或者应该只在极少数的情况下),如果你不上DLL接口级使用它们产生问题。我敢肯定,这方面还有一些更具体的问题和答案。

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

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