Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

MapViewOfFile - ошибка [D5, Win95/98, WinXP]


OlegTrubin ©   (2004-11-25 15:06:00) 

В DLL есть процедура:

procedure MappingGlobalData(var AData: Pointer; ASize: Integer);
var
 i: Integer;
 S: string;
begin
 FMapHandle:= CreateFileMapping(Invalid_Handle_Value, nil, PAGE_READWRITE, 0, ASize, 'SomeName');
 if FMapHandle = 0 then
   RaiseLastWin32Error;

 {проецируем в адресное пространство процесса объект ядра "проекция файла"}
 AData := MapViewOfFile(FMapHandle, FILE_MAP_WRITE, 0, 0, ASize);

 {если неудача, возбуждаем исключение}
 if AData = nil then
 begin
   CloseHandle(FMapHandle);
   RaiseLastWin32Error;
 end;
end;

Суть в том, что  первым вызовом этой процедуры проецируем файл из страничного файла, одного размера, затем это функция вызывается N раз с разными значениями параметра ASize, и нужно каждый раз проецировать  файл из страничного файла соответствующего размера.
Так вот, первый раз все хорошо, а при повторном вызове получаем AData = nil. Это только под win98, под ХР все прокатывает. Почему?
Далее в полученный MMF пишутся данные, которые используются, когда эта DLL грузится в другие процессы. Можно наверно, как у Рихтера описано, использовать частичную передачу физической памяти проецируемым файлам т.е. вызвать это дело 1 раз с ASize большого размера с флагом SEC_RESERVE, а затем с помощью VirtualAlloc передавать память частями, когда надо. Но хотелось бы как выше описано, да вот MapViewOfFile подводит.


Digitman   (2004-11-26 10:53:00) [1]


> OlegTrubin


в ситуации, когда требуемы размер MMF заранее не может быть известен, лучше отказаться от MMF как от механизма интерпроцессного взаимодействия в пользу именованых программных каналов ... с пом.последних процессы могут обмениваться инф.блоками данных произвольного размера


OlegTrubin   (2004-11-25 20:58:00) [2]


> при первом вызове указать маскимальный размер.


Я его не знаю, от юзера зависит, конечно можно, как я уже писал сделать:

> Можно наверно, как у Рихтера описано, использовать частичную
> передачу физической памяти проецируемым файлам т.е. вызвать
> это дело 1 раз с ASize большого размера с флагом SEC_RESERVE,
> а затем с помощью VirtualAlloc передавать память частями,
> когда надо.


Нет сделаю иначе - поменяю слегка логику: в других процессах буду создавать MMF по необходимости, использовать, и уничтожать. Синхронизацию придется замутить.


GuAV   (2004-11-25 20:29:00) [3]

GuAV ©   (25.11.04 19:46) [4]
при первом вызове указать маскимальный размер.


OlegTrubin   (2004-11-25 20:22:00) [4]


> Нужно тогда закрыть старый и создать новый

Ну вызову я UnmapViewOfFile и CloseHandle, но если это дело используется в других процессах, как у меня задумано, тогда объект ядра проекция файла не будет уничтожена. Больше никак?


GuAV   (2004-11-25 19:46:00) [5]

Вы хотите изменить размер FileMapping ?
Нужно тогда закрыть старый и создать новый.
Или при первом вызове указать маскимальный размер.
[2] - видно что оибка ERROR_NOT_ENOUGH_MEMORY.


OlegTrubin   (2004-11-25 19:12:00) [6]


> Т.е. Вы думаете, что создаёте новый FileMapping, а фактически
> открываете старый.


Дак мне того и надо, цитата из вопроса:


> Далее в полученный MMF пишутся данные, которые используются,
> когда эта DLL грузится в другие процессы.


т.е. в других процессах я использую полученный MMF, открывая его с помощи имени.


GuAV   (2004-11-25 18:08:00) [7]

Кстати,
{если неудача, возбуждаем исключение}
if AData = nil then
try
  RaiseLastWin32Error;
finally
  CloseHandle(FMapHandle);
end;


GuAV   (2004-11-25 18:00:00) [8]

'SomeName'

lpName
[in] Pointer to a null-terminated string specifying the name of the mapping object.

If this parameter matches the name of an existing named mapping object, the function requests access to the mapping objectwith the protection specified by flProtect.


Т.е. Вы думаете, что создаёте новый FileMapping, а фактически открываете старый.

Ошибка повторяется
 MappingGlobalData(P, 1000);
 MappingGlobalData(P, 2000);


Ошибка не повторяется
 MappingGlobalData(P, 2000);
 MappingGlobalData(P, 1000);


Наверх

Титульная страница Поиск, карта сайта Написать письмо