2010-06-14 16 views
21

Почему ZeroMemory и подобные вызовы существуют в Windows API, когда уже есть memset и связанные вызовы в стандартной библиотеке C? Какие из них я должен назвать? Я могу догадаться, что ответ «зависит». На что?Почему ZeroMemory и т. Д. Существуют, когда есть memset и т. Д. Уже?

ответ

30

В C и C++, ZeroMemory() и memset() являются точно то же самое.

/* In winnt.h */ 
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length)) 

/* In winbase.h */ 
#define ZeroMemory RtlZeroMemory 

Зачем использовать ZeroMemory()? To make it obvious. Но я предпочитаю memset() в программах на C или C++.

+2

Это большая проблема, как я заметил в своем ответе: оптимизация компиляторов может удалить вызовы 'memset()', поэтому вы действительно хотите использовать что-то, что не будет оптимизировано. –

+3

@ richard.albury в этом случае вы должны использовать SecureZeroMemory, так как ZeroMemory можно было бы оптимизировать. – ya23

5

Поскольку API Windows должен быть агностическим. Он обеспечивает достаточную функциональность для разработчиков, независимо от языка, который они используют. Конечно, в конечном итоге многие функции будут дублировать существующие функциональные возможности, предлагаемые языками.

Вы должны вызвать функции WinAPI (и макросы) непосредственно всякий раз, когда вам нужен определенный уровень контроля - сравнение fopen() с CreateFile(), например. В противном случае, предпочитайте специфические для языка конструкции над вызовами API. По крайней мере, вы получаете больше независимости от платформы.

+3

Я не уверен, как вы напишете язык-агностический макрос. –

+0

ZeroMemory представляется макросом для перекрестной номенклатуры MS-языка. Я проверил, как это возможно, системный трюк для очистки аппаратной памяти, который мог бы быть более эффективным. Вероятно, это просто синтаксический сахар для memset; игнорируй это. http://msdn.microsoft.com/en-us/library/aa366920(VS.85).aspx – msw

+1

@Pete: если у вас есть ZeroMemory, определенный в C stdlib и, скажем, VBA, то ваш кодер использует то же имя для с той же целью и лучше заперта в Microsoft. Объятия и расширения, брат! http://en.wikipedia.org/wiki/Embrace,_extend_and_extinguish – msw

1

Согласно MSDN, ZeroMemory - это макрос. Вероятно, он существует как удобство (например, соглашение об именах) или для обратной совместимости.

+0

Я бы пошел с обратной совместимостью вместе с этими функциями для обработки 32-битных чисел (я забыл имена) для деления и т. Д. –

8

ZeroMemory и такие как часть самого API окон. memset является частью стандартной библиотеки C.

Для типичного кода пользователя, я бы обычно использовал memset (или эквивалент, предоставленный на вашем языке). Если вы пишете код ядра (например, драйвер устройства), используя что-то вроде ZeroMemory, это более привлекательно. Так как ваш код выполняется в режиме ядра в любом случае, вы не берете на себя стоимость переключателя задачи для его использования. Поскольку он уже находится в коде Windows, вы не переносите дополнительный код в своем драйвере, чтобы дублировать то, что уже есть. В то же время вы несете стоимость вызова функции, а в случае или обнуления (особенно небольшого блока), встроенный код может быть значительно быстрее, а rep stosd не занимает много кода (на самом деле, настройка и использование rep stosd может занять меньше кода, вызываемого вызовом функции).

+0

В новых компиляторах Visual Studio 'memset()' является неотъемлемой функцией. Это означает, что он реализован самим компилятором, и во многих случаях вызов функции отсутствует. Компилятор строит его с помощью специально созданного ассемблерного кода для наилучшего использования на основе целевой архитектуры, длины и выравнивания памяти для перезаписываемых данных. – BJovke

+0

@BJovke: это не особенно недавняя инновация. Он возвращается, по крайней мере, к MS C 6.0 (примечание: MS C, а не VC++), который (для памяти, так что это может быть немного неправильно) был выпущен примерно в 1989 или 1990 годах. Я предполагаю, что я не сказал этого непосредственно в ответе, но это было связано с накладными расходами на вызов функции (т. Е. Использование «ZeroMemory» связано с вызовом функции, но использование «memset» часто не будет) , –

3

Потому что, ZeroMemory не требуют линии комментария

3

Я думаю, что один момент состоит в том, что функции распределения памяти должны выглядеть одинаково во всех проектах 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; 

... 
+0

На самом деле из темы, но как разработчик Delphi, я стараюсь использовать MoveMemory (или CopyMemory - они идентичны), когда у меня есть указатели, и Move, когда у меня есть переменные, поэтому мне не нужно использовать «@» или « ^». –

11

Фактическая причина заключается в том, что на другой платформе может быть реализован более эффективно, чем memset. Не забывайте, что Windows NT была разработана как портативная операционная система, она фактически работала на Alpha, MIPS и Power PC. Итак, если платформа fooPC вышла и имеет некоторый способ сборки до ультрабыстрого набора памяти до нуля, ее можно реализовать без изменения API высокого уровня. Это больше не относится к Windows, поскольку теперь оно поддерживает только платформы x86 и amd64, однако это верно для Windows CE.

1

На самом деле, что вам хочу использовать SecureZeroMemory().

Оптимизированный компилятор может удалить вызовы memset(), а SecureZeroMemory() предназначен для предотвращения этого.

Раньше я думал, что звонки не нужны, пока я не наткнулся на этот факт.

+0

Дополнительная ссылка: https://msdn.microsoft.com/en-us/library/ms972826.aspx – Pang