Почему ZeroMemory и подобные вызовы существуют в Windows API, когда уже есть memset и связанные вызовы в стандартной библиотеке C? Какие из них я должен назвать? Я могу догадаться, что ответ "зависит". На чем?
Почему ZeroMemory и т.д. Существуют, когда есть memset и т.д. Уже?
Ответ 1
В C и С++ ZeroMemory()
и memset()
- это то же самое.
/* In winnt.h */
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
/* In winbase.h */
#define ZeroMemory RtlZeroMemory
Зачем использовать ZeroMemory()
? Чтобы сделать это очевидным. Но я предпочитаю memset()
в программах на C или С++.
Ответ 2
Фактическая причина заключается в том, что на другой платформе она может быть реализована более эффективно, чем memset
. Не забывайте, что Windows NT была разработана как портативная операционная система, она фактически работала на Alpha, MIPS и Power PC. Итак, если платформа fooPC вышла и имеет некоторый способ сборки до ультрабыстрого набора памяти до нуля, ее можно реализовать без изменения API высокого уровня. Это больше не относится к Windows, поскольку теперь оно поддерживает только платформы x86 и amd64, однако это все еще верно для Windows CE.
Ответ 3
ZeroMemory
, и они являются частью самого API Windows. memset
является частью стандартной библиотеки C.
Для типичного кода userland я обычно использовал бы memset
(или эквивалент, предоставленный выбранным вами языком). Если вы пишете код ядра (например, драйвер устройства), использование чего-то типа ZeroMemory
более привлекательно. Так как ваш код выполняется в режиме ядра в любом случае, вы не берете на себя стоимость переключателя задачи для его использования. Поскольку он уже находится в коде Windows, вы не переносите дополнительный код в своем драйвере, чтобы дублировать то, что уже есть. В то же время вы несете стоимость вызова функции, а в случае или обнуления (особенно небольшого блока), встроенный код может быть значительно быстрее, а rep stosd
не требует большого количества кода (в факт, настройка и использование rep stosd
может занять меньше кода, который вызывает функцию).
Ответ 4
Потому что API Windows должен быть агностическим. Он обеспечивает достаточную функциональность для разработчиков, независимо от языка, который они используют. Конечно, в конечном итоге многие функции будут дублировать существующие функциональные возможности, предлагаемые языками.
Вы должны вызывать функции winapi (и макросы) напрямую, когда вам нужен определенный уровень контроля - например, сравнить fopen()
с CreateFile()
. В противном случае, предпочитайте специфические для языка конструкции над вызовами API. По крайней мере, вы получаете больше независимости от платформы.
Ответ 5
Потому что ZeroMemory не требует строки комментария
Ответ 6
Я думаю, что один момент состоит в том, что функции распределения памяти должны выглядеть одинаково во всех проектах Win32, независимо от языка программирования. Действительно, как указывалось ранее, в C, ZeroMemory - фактически memset, функция C. В Delphi
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;
...
Ответ 7
Согласно MSDN, ZeroMemory - это макрос. Он, вероятно, существует как удобство (например, соглашение об именах) или для обратной совместимости.
Ответ 8
На самом деле, вы хотите использовать SecureZeroMemory()
.
Оптимизирующий компилятор может удалить вызовы memset()
, а SecureZeroMemory()
предназначен для предотвращения этого.
Раньше я думал, что вызовы ZeroMemory()
не нужны, пока не натолкнулись на этот факт.