Dlaczego ZeroMemory i podobne wywołania istnieją w interfejsie API systemu Windows, gdy istnieją już odwołania do zestawów pamięci i powiązanych z nimi w bibliotece standardowej C? Których powinienem zadzwonić? Mogę zgadnąć, że odpowiedź jest "zależna". Na czym?Dlaczego ZeroMemory itp. Istnieje, gdy już są pliki memset itp.?
Odpowiedz
w C i C++, ZeroMemory()
i memset()
są dokładnie to samo.
/* In winnt.h */
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))
/* In winbase.h */
#define ZeroMemory RtlZeroMemory
Dlaczego warto używać ZeroMemory()
? To make it obvious. Ale wolę memset()
w programach C lub C++.
Ponieważ interfejs API systemu Windows powinien być agnostykiem językowym. Zapewnia wystarczającą funkcjonalność dla programistów, niezależnie od używanego języka. Oczywiście, w końcu wiele funkcji powiela istniejącą funkcjonalność oferowaną przez języki.
powinien wywoływać funkcje WinAPI (i makr) bezpośrednio, kiedy trzeba pewien poziom kontroli - porównanie fopen()
z CreateFile()
na przykład. W przeciwnym razie preferuj konstrukcje specyficzne dla języka za pośrednictwem wywołań API. Przynajmniej zyskujesz większą niezależność od platformy.
Nie jestem pewien, w jaki sposób można napisać makro-agnostyczny język. –
ZeroMemory wydaje się być makrem dla krzyżowej nomenklatury w języku MS. Sprawdziłem, jako że prawdopodobnie była to sztuczka systemowa do czyszczenia pamięci sprzętowej, która mogłaby być bardziej wydajna. Jest to prawdopodobnie po prostu syntaktyczny cukier do memsetu; zignoruj to. http://msdn.microsoft.com/en-us/library/aa366920(VS.85).aspx – msw
@Pete: jeśli masz ZeroMemory zdefiniowane w C stdlib i - powiedzmy VBA - to twój koder używa tej samej nazwy dla ten sam cel i jest lepiej zamknięty w Microsoft. Obejmuj i przedłużaj, bracie! http://en.wikipedia.org/wiki/Embrace,_extend_and_extinguish – msw
Zgodnie z MSDN, ZeroMemory jest makro. Prawdopodobnie istnieje dla wygody (np. Konwencja nazewnictwa) lub dla kompatybilności wstecznej.
Byłbym kompatybilny z poprzednimi wersjami, wraz z tymi funkcjami do obsługi liczb 32-bitowych (nie pamiętam nazw) dla podziału itp. –
ZeroMemory
i takie są częścią samego API systemu Windows. memset
jest częścią standardowej biblioteki C.
Dla typowego kodu użytkownika normalnie użyłbym memset
(lub odpowiednika dostarczonego przez wybrany przez ciebie język). Jeśli piszesz kod jądra (np. Sterownik urządzenia) używając czegoś takiego jak ZeroMemory
jest bardziej atrakcyjny. Ponieważ Twój kod jest wykonywany w trybie jądra, nie ponosisz kosztów przełączania zadań, aby go użyć. Ponieważ jest już w kodzie systemu Windows, nie przenosisz dodatkowego kodu do sterownika, aby powielić to, co już jest. W tym samym czasie ponosisz koszt wywołania funkcji, aw przypadku lub zerowania (zwłaszcza w małym bloku) pamięć, kod wewnętrzny może być znacznie szybszy, a kod rep stosd
nie zajmuje dużo kodu (w rzeczywistości konfiguracja i używanie rep stosd
może zająć mniej kodu niż wywołanie funkcji).
W nowszych kompilatorach Visual Studio 'memset()' jest funkcją wewnętrzną. Oznacza to, że jest on implementowany przez sam kompilator iw wielu przypadkach nie ma wywołania funkcji. Kompilator dodaje do niego specjalnie spreparowany kod zespołu, aby uzyskać najlepsze wyniki w oparciu o docelową architekturę, długość i wyrównanie pamięci nadpisywanych danych. – BJovke
@BJovke: to nie jest ostatnia innowacja. Wraca do co najmniej MS C 6.0 (uwaga: MS C, nie VC++), która (dzieje się dla pamięci, więc może być trochę źle) została wydana około 1989 lub 90. Chyba nie powiedziałem tego wprost w odpowiedzi, ale to było wspomnienie o obciążeniu wywołanym przez funkcję (tzn. Że użycie 'ZeroMemory' wymagałoby wywołania funkcji, ale użycie' memset' często by tego nie zrobiło) . –
Bo ZeroMemory nie wymagają linię komentarza
Myślę, że jednym z punktów jest to, że funkcje alokacji pamięci powinny wyglądać tak samo we wszystkich projektach Win32, niezależnie od języka programowania. Rzeczywiście, jak już wskazano wcześniej, w C, ZeroMemory jest faktycznie w stanie złożonym, funkcja C. W języku Delphi:
procedure ZeroMemory(Destination: Pointer; Length: DWORD);
begin
FillChar(Destination^, Length, 0);
end;
gdzie FillChar jest funkcją Delphi. I tak dalej:
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;
...
Naprawdę poza tematem, ale jako programista Delphi, używam MoveMemory (lub CopyMemory - są identyczne), gdy mam wskaźniki, i poruszam się, gdy mam zmienne, więc nie muszę używać "@" lub "^". –
Rzeczywista przyczyna jest taka, że na innej platformie może być realizowane w sposób bardziej efektywny niż memset
. Nie zapominaj, że Windows NT został zaprojektowany jako wysoce przenośny system operacyjny, faktycznie działający na Alpha, MIPS i Power PC. Tak więc, jeśli platforma fooPC wyszła i ma jakikolwiek sposób montażu do ultraszybkiej pamięci ustawionej na zero, może być zaimplementowana bez zmiany interfejsu API wysokiego poziomu. Nie dotyczy to już systemu Windows, ponieważ teraz obsługuje tylko platformy x86 i amd64, ale nadal jest tak w przypadku systemu Windows CE.
W rzeczywistości, do korzystania z usługi jest: SecureZeroMemory()
.
Kompilator optymalizacyjny może usuwać połączenia pod numer memset()
, a SecureZeroMemory()
ma na celu zapobieganie temu.
Kiedyś myślałem, że rozmowy ZeroMemory()
były niepotrzebne, dopóki nie natknąłem się na ten fakt.
Dodatkowe informacje: https://msdn.microsoft.com/en-us/library/ms972826.aspx – Pang
- 1. Dlaczego mDNS (Bonjour, Avahi, itp.) Używa UDP?
- 2. Polling, Comet, WebSockets, itp.
- 3. Gdzie zadeklarować struktury itp.?
- 4. % temp% itp. Nie działa
- 5. Po co używać Apache lub Nginx, itp?
- 6. Jakie są ekwiwalenty C# Java getClass(), isAssignableFrom() itp.?
- 7. Nauka Java EE, jboss, itp.
- 8. Program nasłuchujący minimalizowanie, maksymalizowanie itp.
- 9. Wyjaśnienie CAR, CDR, CADAR, itp.
- 10. Czy istnieje mikroformat do oznaczania zdań, słów, części mowy itp.
- 11. Dlaczego warto używać LISP dzisiaj, kiedy są Scala, Erlang, Haskell itp.
- 12. Programowanie funkcjonalne - standardowe symbole, diagramy itp.
- 13. Co to są GeneratedMethodAccessor1,2, itp. I dlaczego nie można ich znaleźć?
- 14. PouchDb na PAAS (Heroku, Bluemix, itp.)
- 15. Dlaczego system Windows 64 nadal korzysta z user32.dll itp.?
- 16. destruktory z wbudowanych typów (int, char itp ..)
- 17. OmniAuth + Pulling Tweets, Miejsca FB, itp.
- 18. Efektywność wykrywania błędów (CRC, suma kontrolna itp.)
- 19. Przepisywanie C++ makro jako funkcję itp
- 20. Zalecane narzędzia do wykrywania twarzy/SDK/itp.
- 21. eliksir Logger do listy, krotki itp
- 22. Zatrzymaj automatyczne hiperłącze w Outlooku, Gmailu itp.
- 23. Dostosowywanie wstążki WPF 4.5 (style, szablony itp.)
- 24. Obiekt już istnieje w RSACryptoServiceProvider
- 25. Visual Studio: metody zwinięcia, ale nie komentarze (podsumowanie itp.)
- 26. Offline (CD, Thumb Drive, itp.) No-Install HTML + Video Presentation?
- 27. Zmuszanie ERL -make przekompilować pliki gdy makra są zmieniane
- 28. Niezaufany kod GPGPU (OpenCL itp.) - czy jest bezpieczny? Jakie ryzyko?
- 29. działka ggplot2 bez osi, legend, itp.
- 30. Casting moją klasę do Int64, Double itp
To jest większy problem, jak zauważyłem w mojej odpowiedzi: optymalizacja kompilatorów może usunąć wywołania 'memset()', więc naprawdę chcesz użyć czegoś, co nie zostanie zoptymalizowane. –
@ richard.albury w takim przypadku powinieneś użyć SecureZeroMemory, ponieważ ZeroMemory może być zoptymalizowane. – ya23