31

ZeroMemory()当 C 标准库中已经存在 memset 和相关调用时,为什么Windows API 中存在 , 和类似的调用?我应该打电话给哪些?我猜答案是“取决于”。什么?

4

8 回答 8

43

在 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++ 程序。

于 2010-06-14T15:33:42.787 回答
11

实际原因是在不同的平台上,它可能以比memset. 不要忘记 Windows NT 被设计为一个高度便携的操作系统,它实际上运行在 Alpha、MIPS 和 Power PC 上。因此,如果 fooPC 平台出现并且有一些组装方式可以将内存超快速设置为零,则可以在不更改高级 API 的情况下实现它。这不再适用于 Windows,因为现在它只支持 x86 和 amd64 平台,但它仍然适用于 Windows CE。

于 2010-06-15T00:57:29.617 回答
9

ZeroMemory等等都是windows API本身的一部分。memset是 C 标准库的一部分。

对于典型的用户态代码,我通常会使用memset(或您选择的语言提供的等效代码)。如果您正在编写内核代码(例如,设备驱动程序),使用类似的东西ZeroMemory更有吸引力。由于您的代码无论如何都在内核模式下执行,因此您不会产生使用它的任务切换成本。由于它已经在 Windows 代码中,因此您无需在驱动程序中携带额外的代码来复制已经存在的内容。同时,您确实会产生函数调用的成本,并且在将内存归零(尤其是一小块)的情况下,内联代码可能会明显更快,并且 arep stosd不会占用太多代码(实际上,设置启动和使用rep stosd可能会比函数调用花费更少的代码)。

于 2010-06-14T15:12:45.677 回答
6

实际上,您使用的是SecureZeroMemory().

优化编译器可以删除对 的调用memset(),并且SecureZeroMemory()旨在防止这种情况发生。

ZeroMemory()在我遇到这个事实之前,我曾经认为这些电话是不必要的。

于 2013-02-20T22:09:14.770 回答
6

因为 Windows API 应该与语言无关。它为开发人员提供了足够的功能,无论他们使用什么语言。当然,最终许多功能将复制语言提供的现有功能。

每当您需要一定程度的控制时,您都应该直接调用 winapi 函数(和)——例如,比较fopen()一下。CreateFile()否则,比起 API 调用,更喜欢特定于语言的构造。至少,您获得了更多的平台独立性。

于 2010-06-14T15:10:24.013 回答
4

因为,ZeroMemory 不需要注释行

于 2010-06-14T15:13:01.387 回答
3

我认为有一点是所有 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;

...
于 2010-06-14T15:56:23.600 回答
1

根据MSDN,ZeroMemory 是一个宏。它可能是为了方便(例如,命名约定)或向后兼容而存在的。

于 2010-06-14T15:10:41.033 回答