Memory mapped
От: xteam777  
Дата: 31.05.18 15:59
Оценка:
Уважаемые. Прошу помощи.

Задача в одном процессе записывать TBitmap в MemoryMappedFile, а в другом считывать.

Запись делаю так:
procedure SaveBitmapToMMF;
var
  CurBitmapInfoSize: Integer;
begin
  MemStream.Clear;
  SaveBitmap.SaveToStream(MemStream);
  CurBitmapInfoSize := MemStream.size;
//  CurBitmapInfoSize := PBitmapFileHeader(MemStream.Memory)^.bfOffBits - SizeOf(TBitmapFileHeader) + sizeof(pSize);
  try
    if BitmapInfoSize <> CurBitmapInfoSize then
    begin
      BitmapInfoSize := CurBitmapInfoSize;
 
      UnmapViewOfFile(pMap); //Disposes the mem map
      if hMap > 0 then
        CloseHandle(hMap);
 
      hMap := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0,
        BitmapInfoSize, PWideChar(WideString('VCS_SCREEN_SESSION_' + IntToStr(CurrentSessionID))));
      pMap := MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, BitmapInfoSize + sizeof(BitmapInfoSize));
    end;
 
    MemStream.Position := 0;
    CopyMemory(pMap, @BitmapInfoSize, sizeof(BitmapInfoSize));
    MemStream.Read((PByte(pMap) + sizeof(BitmapInfoSize))^, BitmapInfoSize);
  finally
//    CloseHandle(hMap);
  end;
end;


Считывание:
Result := TBitmap.Create;
 
  try
    hMap := OpenFileMapping(FILE_MAP_READ, False, PWideChar(WideString('VCS_SCREEN_SESSION_' + IntToStr(SessionID))));
    err := GetLastError;
    if hMap = 0 then
      Exit;
 
    pMap := MapViewOfFile(hMap,//дескриптор "проецируемого" объекта
                            FILE_MAP_READ,// разрешение чтения/записи
                            0,0,
                            SizeOf(int64));//размер буфера
 
    CopyMemory(@pSize, pMap, SizeOf(int64));
    UnmapViewOfFile(pMap);
 
    pMap := MapViewOfFile(hMap,//дескриптор "проецируемого" объекта
                            FILE_MAP_READ,// разрешение чтения/записи
                            0,0,
                            pSize + SizeOf(int64));//размер буфера
 
    MemStream := TMemoryStream.Create;
    MemStream.Write((PByte(pMap) + sizeof(pSize))^, pSize);
    MemStream.Position := 0;
    Result.LoadFromStream(MemStream);
 
    UnmapViewOfFile(pMap);
  finally
    CloseHandle(hMap);
  end;



Как правильно записать в начало размер, а потом содержимое? Сейчас в переменную pSize считывается какой-то мусор.
Размер нужен чтобы потом считать сначала размер, а потом уже содержимое. Может есть другой способ определить размер Mapped файла?

И еще вопрос. Как реализовать взаимодействие между процессами так, чтобы небыло одновременно и записи и считывания файла?
Re: Memory mapped
От: kov_serg Россия  
Дата: 31.05.18 18:29
Оценка:
Здравствуйте, xteam777, Вы писали:


X>Задача в одном процессе записывать TBitmap в MemoryMappedFile, а в другом считывать.

Чем pipe-ы не устраивают?
https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa365592(v=vs.85).aspx

То что вы делаете в ms делают так
https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa366551(v=vs.85).aspx
Re[2]: Memory mapped
От: xteam777  
Дата: 01.06.18 15:35
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Здравствуйте, xteam777, Вы писали:


Я так и делаю.
Не получается правильно посчитать смещение в этой строке. Данные битмапа затирают первые 8 байт размера

MemStream.Read((PByte(pMap) + sizeof(BitmapInfoSize))^, BitmapInfoSize);


X>>Задача в одном процессе записывать TBitmap в MemoryMappedFile, а в другом считывать.

_>Чем pipe-ы не устраивают?
_>https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa365592(v=vs.85).aspx

_>То что вы делаете в ms делают так

_>https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa366551(v=vs.85).aspx
Re[3]: Memory mapped
От: kov_serg Россия  
Дата: 01.06.18 21:40
Оценка:
Здравствуйте, xteam777, Вы писали:

X>Я так и делаю.

X>Не получается правильно посчитать смещение в этой строке. Данные битмапа затирают первые 8 байт размера

X>
X>MemStream.Read((PByte(pMap) + sizeof(BitmapInfoSize))^, BitmapInfoSize);
X>


1. У вас sizeof(BitmapInfoSize)==sizeof(int64) ?
2. Почему BitmapInfoSize а не BitmapInfoSize+sizeof(BitmapInfoSize)
hMap := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, BitmapInfoSize, PWideChar(WideString('VCS_SCREEN_SESSION_' + IntToStr(CurrentSessionID))));

3. Как вы синхронизируете ваши действия (что бы не читать пока оно еще пишет)?
4. Нафига SaveBitmap.SaveToStream(MemStream) если можно SaveBitmap.SaveToStream(pipe)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.