ZeroMemory()
当 C 标准库中已经存在 memset 和相关调用时,为什么Windows API 中存在 , 和类似的调用?我应该打电话给哪些?我猜答案是“取决于”。什么?
8 回答
在 C 和 C++ 中,ZeroMemory()
和memset()
是完全相同的东西。
/* In winnt.h */
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
/* In winbase.h */
#define ZeroMemory RtlZeroMemory
那为什么要用ZeroMemory()
呢?让它显而易见。但我更喜欢memset()
C 或 C++ 程序。
实际原因是在不同的平台上,它可能以比memset
. 不要忘记 Windows NT 被设计为一个高度便携的操作系统,它实际上运行在 Alpha、MIPS 和 Power PC 上。因此,如果 fooPC 平台出现并且有一些组装方式可以将内存超快速设置为零,则可以在不更改高级 API 的情况下实现它。这不再适用于 Windows,因为现在它只支持 x86 和 amd64 平台,但它仍然适用于 Windows CE。
ZeroMemory
等等都是windows API本身的一部分。memset
是 C 标准库的一部分。
对于典型的用户态代码,我通常会使用memset
(或您选择的语言提供的等效代码)。如果您正在编写内核代码(例如,设备驱动程序),使用类似的东西ZeroMemory
更有吸引力。由于您的代码无论如何都在内核模式下执行,因此您不会产生使用它的任务切换成本。由于它已经在 Windows 代码中,因此您无需在驱动程序中携带额外的代码来复制已经存在的内容。同时,您确实会产生函数调用的成本,并且在将内存归零(尤其是一小块)的情况下,内联代码可能会明显更快,并且 arep stosd
不会占用太多代码(实际上,设置启动和使用rep stosd
可能会比函数调用花费更少的代码)。
实际上,您要使用的是SecureZeroMemory()
.
优化编译器可以删除对 的调用memset()
,并且SecureZeroMemory()
旨在防止这种情况发生。
ZeroMemory()
在我遇到这个事实之前,我曾经认为这些电话是不必要的。
因为 Windows API 应该与语言无关。它为开发人员提供了足够的功能,无论他们使用什么语言。当然,最终许多功能将复制语言提供的现有功能。
每当您需要一定程度的控制时,您都应该直接调用 winapi 函数(和宏)——例如,比较fopen()
一下。CreateFile()
否则,比起 API 调用,更喜欢特定于语言的构造。至少,您获得了更多的平台独立性。
因为,ZeroMemory 不需要注释行
我认为有一点是所有 Win32 项目中的内存分配函数应该看起来相同,与编程语言无关。事实上,正如之前所指出的,在 C 中,ZeroMemory 实际上是 memset,即 C 函数。在德尔福,
procedure ZeroMemory(Destination: Pointer; Length: DWORD);
begin
FillChar(Destination^, Length, 0);
end;
其中 FillChar 是 Delphi 函数。等等:
procedure MoveMemory(Destination: Pointer; Source: Pointer; Length: DWORD);
begin
Move(Source^, Destination^, Length);
end;
procedure FillMemory(Destination: Pointer; Length: DWORD; Fill: Byte);
begin
FillChar(Destination^, Length, Fill);
end;
...
根据MSDN,ZeroMemory 是一个宏。它可能是为了方便(例如,命名约定)或向后兼容而存在的。