Как зарезервировать память для MapViewOfFileEx?

173
07 октября 2018, 14:00

Работая с мапингом под виндой, столкнулся с такой проблемой, не получается зарезервировать буфер под MapViewOfFileEx.

При работе с файлом, как я понимаю, используется DMA, DMA позволяет ускорить обращение к памяти, если делается "выровняное" обращение. Если вызвать функцию с NULL указателем, то Windows сама определит место для мапинга, калькуляция занимает время... но... всётаки, можно ли "зараннее" зарезервировать место для мапинга? И быть уверенным, что окно всегда есть, и его никто "не украдёт" (что будет свободный линейный кусок на 64к)? Вот так реализовал я "повторный" мапинг. Если я подсовываю буфер, который зарезервировал с помощью VirtualAlloc MEM_RESERVE или MEM_RESERVE + MEM_COMMIT, то MapViewOfFileEx даёт ошибку

ERROR_INVALID_ADDRESS 487 (0x1E7) Attempt to access invalid address.

Пример (грубо)

DWORD AllocationGranularity = 65536;
void * mWnd = VirtualAlloc(0,AllocationGranularity , MEM_RESERVE, PAGE_READWRITE);
VirtualAlloc(mWnd,AllocationGranularity , MEM_COMMIT, PAGE_READWRITE);
void * wnd = MapViewOfFileEx(hMap, FILE_MAP_ALL_ACCESS, 0,0     AllocationGranularity,mWnd);

Или... можно использовать повторно то же место куда винда его определила, а если это место станет занятым, то сбрасывать указатель в ноль, и повторно вызывать MapViewOfFileEx с нулём? (Но тут есть вероятность, что свободной памяти может не оказаться)

Возможно есть другое хорошее решение?

Answer 1

Все делается с точностью до наоборот. Вначале мапится регион с флагом SEC_RESERVE, а потом этому региону делается MEM_COMMIT

DWORD AllocationGranularity = 65536;
HANDLE hMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_RESERVE,
  0, AllocationGranularity, NULL);
void * wnd = MapViewOfFileEx(hMap, FILE_MAP_ALL_ACCESS, 0, 0, AllocationGranularity, NULL);
void * mWnd = VirtualAlloc(wnd, AllocationGranularity, MEM_COMMIT, PAGE_READWRITE);

Проверка и обработка ошибок по вкусу

Ну и не забываем про страницы и гранулы

READ ALSO
Можно ли динамически определить, как был создан объект - на куче или в стеке?

Можно ли динамически определить, как был создан объект - на куче или в стеке?

Например проверять объект при очищении контейнера:

158
Как правильно создавать Dialog?

Как правильно создавать Dialog?

У меня аварийно завершается программа после того как я открываю диалог повторноПочему так происходить ? Может это быть из-за пустого Деструктор?...

168
C++ delete и delete[]

C++ delete и delete[]

Ясное дело, что по Стандарту вызовы malloc()/free()*, **new/delete и new[]/delete[] должны быть строго парными, иначе неопределенное поведение

148
В чем смысл использования auto?

В чем смысл использования auto?

В сети нашел статьи, например такиую: статья

149