使用后丢弃DLL的资源

时间:2014-06-12 08:15:05

标签: c++ windows winapi dll portable-executable

我正在使用嵌入式二进制资源创建一个dll。目前,当我加载此DLL时,它将内存映射到我的进程地址空间。问题是嵌入式二进制资源是巨大的,我不想在使用它之后保留它。

我尝试查找有关此文档的文档,显然PE文件中有一些部分没有得到内存映射(重定位部分)。此外,我可以创建新的部分并将其标记为IMAGE_SCN_MEM_DISCARDABLE,但在内核模式之外忽略此标志。

有一个win API函数,它支持为16位Windows释放资源但不会向前运行32位。 documentation表示"此功能已过时,仅支持向后兼容16位Windows。对于32位Windows应用程序,不必释放使用LoadResource加载的资源。如果在32位或64位Windows系统上使用,此函数将返回FALSE"。我不知道他们的意思,但似乎他们并不期望资源是巨大的,可以容纳在地址空间。

在我使用完资源后,有没有办法让我放弃我加载的资源?

1 个答案:

答案 0 :(得分:2)

如果需要,系统会丢弃它们。只要你没有提到内存,如果系统需要物理内存来处理其他内容,就可以将其丢弃并分页。因此,它不会停止用于需要物理内存的物理内存。

尽管如此,链接的资源并不是很大。关键是模块映射到连续的内存范围。如果你的模块非常庞大,那么找到这样一个连续的内存范围可能是不可能的。此外,模块的地址范围是为资源的整个生命周期保留的。这意味着进程中的任何其他内容都不能使用该虚拟内存地址范围。因此,即使可以找到连续的地址范围,它也永远保留给模块,并且该地址范围不能用于其他任何地方。这很容易成为32位应用程序的问题。

因此,通过将巨大的资源放在内存中,您不会长期耗费物理资源,但是您将对虚拟内存地址空间资源施加不可避免的限制。

得出的结论是,这些巨大的对象应该保存在外部文件中,而不是作为资源链接到模块。如果绝对必须在PE模块中使用资源,则将资源放入单独的DLL中。使用LoadLibrary加载DLL,使用从LoadLibrary获得的模块句柄拉出资源,然后使用FreeLibrary卸载DLL。