fișier de mapare de memorie pe WinAPI, precum și o întrebare privind - testul de cunoștințe cu un asterisc, note

Afișați fișierele din memoria ne sunt folosite pentru articole pe OpenGL pe activitatea cu modele și texturi. dar nu am examinat în detaliu modul în care funcționează. Și, deși sunt destul de sigur că mulți cititori acestui blog deja familiarizați cu fișierele din memoria de afișare, eu încă simțit că este necesar să scrie notele corespunzătoare pentru acei cititori care nu cunosc mecanismul. Astăzi ne uităm la modul în care totul funcționează sub Windows.

Șeful unei structuri de stocare mâner fișier, mânerul de afișare, dimensiunea fișierului, și un pointer la locația de memorie cu harta:

struct FileMapping # 123;
HANDLE hFile;
HANDLE hMapping;
fsize size_t;
nesemnate char * dataPtr;
# 125; ;

Luați în considerare citirea dintr-un fișier utilizând maparea.

MÂNER hFile = CreateFile # 40; fname, GENERIC_READ, 0. nullptr, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, nullptr # 41; ;
dacă # 40; hFile == INVALID_HANDLE_VALUE # 41; # 123;
std. cerr <<"fileMappingCreate - CreateFile failed, fname = "
< nullptr reveni;
# 125;

Cu procedura CreateFile suntem deja familiarizați cu următoarea notă: Aflați cum să lucrați cu fișiere prin intermediul API-ului Windows. Să mergem mai departe.

Obțineți dimensiunea fișierului:

DWORD dwFileSize = GetFileSize # 40; hFile, nullptr # 41; ;
dacă # 40; dwFileSize == INVALID_FILE_SIZE # 41; # 123;
std. cerr <<"fileMappingCreate - GetFileSize failed, fname = "
< CloseHandle # 40; hFile # 41; ;
nullptr reveni;
# 125;

A doua procedură argument GetFileSize primește un pointer la o intrare DWORD pentru partea veche a dimensiunea fișierului. Este trecut ca nullptr argument, am limitat dimensiunea fișierului, care poate fi returnat. Dacă dimensiunea fișierului este de 4 GB sau mai mult, procedura va returna o eroare.

MÂNER hMapping = CreateFileMapping # 40; hFile, nullptr, PAGE_READONLY, 0. 0,
nullptr # 41; ;
dacă # 40; hMapping == nullptr # 41; # 123;
std. cerr <<"fileMappingCreate - CreateFileMapping failed, fname = "
< CloseHandle # 40; hFile # 41; ;
nullptr reveni;
# 125;

Rețineți că hMapping verificat pentru nullptr egalitate. Acesta nu este un bug - în conformitate cu MSDN, în cazul CreateFileMapping eroare returnează într-adevăr un pointer nul în loc INVALID_HANDLE_VALUE, așa cum s-ar aștepta. O astfel de inconsecvență, din păcate, se întâmplă din când în când în WinAPI. Am întâmpinat deja această problemă, studiind lucrările cu registru.

În cele din urmă, vom obține un pointer la locația de memorie cu harta folosind procedura MapViewOfFile:

unsigned char * dataPtr = # 40; unsigned char * # 41; MapViewOfFile # 40; hMapping,
FILE_MAP_READ,
0
0
dwFileSize # 41; ;
dacă # 40; dataPtr == nullptr # 41; # 123;
std. cerr <<"fileMappingCreate - MapViewOfFile failed, fname = "
< CloseHandle # 40; hMapping # 41; ;
CloseHandle # 40; hFile # 41; ;
nullptr reveni;
# 125;

Apoi umple structura FileMapping și returnează un pointer la ea ca rezultat:

FileMapping * cartografiere = # 40; FileMapping * # 41; malloc # 40; sizeof # 40; FileMapping # 41; # 41; ;
dacă # 40; cartografiere == nullptr # 41; # 123;
std. cerr <<"fileMappingCreate - malloc failed, fname = "
< UnmapViewOfFile # 40; dataPtr # 41; ;
CloseHandle # 40; hMapping # 41; ;
CloseHandle # 40; hFile # 41; ;
nullptr reveni;
# 125;

cartografiere -> hFile = hFile;
cartografiere -> hMapping = hMapping;
cartografiere -> dataPtr = dataPtr;
cartografiere -> fsize = # 40; size_t # 41; dwFileSize;

Atunci când afișajul nu este necesară, nu uitați să-l închidă:

UnmapViewOfFile # 40; cartografiere -> dataPtr # 41; ;
CloseHandle # 40; cartografiere -> hMapping # 41; ;
CloseHandle # 40; cartografiere -> hFile # 41; ;
gratuit # 40; cartografiere # 41; ;

După cum puteți vedea, totul este ușor. Sursele pentru acest articol pot fi găsite aici.

Ca și postul? Împărtășește cu alții:

(Trebuie să includeți JS)

articole similare