Как правильно использовать File Mapping и передать данные дочернему процессу? - PullRequest
4 голосов
/ 21 февраля 2012

Мое приложение выполняет другой процесс (" update.exe "), и я хотел бы передать большие данные (возможно, запись) из моего приложения в программу update .

Использование командной строки для передачи параметра (-ов) данных не вариант, так как данные слишком велики (также размер данных может изменяться).

Как правильно создать CreateFileMapping / MapViewOfFile / UnmapViewOfFile,
затем выполняю мой update.exe ,
наконец получение данных в программе update.exe (OpenFileMapping),
и освобождая все дескрипторы (из основного приложения и update.exe ), чтобы у меня не было утечек памяти / дескрипторов?

Код был бы хорош (№ JCL, пожалуйста). С ++ тоже хорошо. Спасибо.


Редактировать: Я думаю, что моя основная проблема заключается в том, как «сигнализировать» основному приложению о UnmapViewOfFile и CloseHandle после update.exe завершения чтения данных. (или, может быть, мне нужно использовать OpenFileMapping с bInheritHandle, установленным на True в моем дочернем процессе?)
Вот Пример . Как Второй процесс может прочитать данные, если основной процесс вызывает UnmapViewOfFile и CloseHandle?.

Ответы [ 2 ]

2 голосов
/ 21 февраля 2012

Хороший пример вы можете найти на Межпроцессное взаимодействие .Правильный метод зависит от размера ваших данных и требований к скорости.

1 голос
/ 21 февраля 2012

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

Если вам необходимо использовать этот тип системы для управления обменом сообщениями между службами и приложениями или приложениями, работающими с разными учетными данными пользователя, убедитесь, что вы запускаете FileName с «Global \»

procedure TRawFeedImageQueue.CreateFileMap;
var
  SysInfo: TSystemInfo;
  sd: TSecurityDescriptor;
begin
  GetSystemInfo( SysInfo );
  MapGranularity := SysInfo.dwAllocationGranularity;
  MapSize := sizeof( TRawFeedImageQueueData );

  FSecObjOk := CreateWorldAccessDescriptor( sd, GENERIC_ALL );

  FileMappingHandle := CreateFileMapping( $FFFFFFFF, @sd, PAGE_READWRITE OR SEC_COMMIT, 0, MapSize and $FFFFFFFF, PChar(FFileName) );
  if FileMappingHandle <> 0 then
  begin
    MapView := MapViewOfFile( FileMappingHandle, FILE_MAP_ALL_ACCESS, 0, 0, MapSize );
  end
  else
  begin
    MapView := nil;
  end;
end;

procedure TRawFeedImageQueue.ReleaseFileMap;
begin
  if FileMappingHandle <> 0 then
  begin
    unMapViewOfFile( MapView );
    CloseHandle( FileMappingHandle );
  end;
end;

Надеюсь, это немного поможет.

Обновление

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

...