![]() |
MemoryMappedFiles - Geht ja gar nicht
Hey,
so langsam zweifele ich an meinen Fähigkeiten. Folgende Unit hatte ich mir gebastelt:
Delphi-Quellcode:
Anwendung [1] schreibt nun mittels WriteMMFString mehrere String und mittels WriteToMMF einen Cardinal. Anwendung [2] ließt nun mittels ReadMMFString die Strings wieder aus und mittels ReadFromMMF den Cardinal. Das Problem ist folgendes: Mindestens einer der Werte wird nicht ausgelesen. Es wird allerhöchstens 00 zurückgegeben.
procedure WriteToMMF(Filename: PChar; Data: Pointer; Len: Int64);
var hFile: Cardinal; Mem: Pointer; begin hFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, Len, Filename); if hFile <> 0 then begin try Mem := MapViewOfFile(hFile, FILE_MAP_WRITE, 0, 0, 0); if Assigned(Mem) then begin try CopyMemory(Mem, Data, Len); finally //UnmapViewOfFile(Mem); end; end; finally //CloseHandle(hFile); end; end; end; function ReadFromMMF(Filename: PChar; Len: Int64): Pointer; var hFile: Cardinal; begin hFile := CreateFileMapping($FFFFFFFF, nil, PAGE_READONLY, 0, Len, Filename); if hFile <> 0 then begin try Result := MapViewOfFile(hFile, FILE_MAP_READ, 0, 0, 0); finally //CloseHandle(hFile); end; end else begin Result := nil; end; end; procedure WriteMMFString(Filename: PChar; Value: String); var Buf: Pointer; Len: Int64; hMem: Cardinal; begin Len := Length(Value); hMem := GlobalAlloc(GPTR, Len + SizeOf(Int64)); Buf := GlobalLock(hMem); try CopyMemory(Buf, @Len, SizeOf(Int64)); CopyMemory(Pointer(Cardinal(Buf) + SizeOf(Int64)), @Value[1], Len); WriteToMMF(Filename, Buf, Len + SizeOf(Int64)); finally GlobalUnlock(hMem); GlobalFree(hMem); end; end; function ReadMMFString(Filename: PChar; var Len: Int64): Pointer; var Data: Pointer; begin Result := nil; Data := ReadFromMMF(Filename, SizeOf(Int64)); try if Assigned(Data) then begin Len := Cardinal(Data^); Data := ReadFromMMF(Filename, SizeOf(Int64) + Len); try if Assigned(Data) then begin Result := GlobalLock(GlobalAlloc(GPTR, Len)); CopyMemory(Result, Pointer(Cardinal(Data) + SizeOf(Int64)), Len); end; finally //UnmapViewOfFile(Data); end; end; finally //UnmapViewOfFile(Data); end; end; Irgendwie scheine ich das Prinzip aber auch noch nicht ganz verstanden zu haben. Die auskommentierten Befehle darf ich nicht aufrufen, weil sonst schonmal direkt überhauptnichts ankommt. Das Problem ist auch, dass Anwendung [2] normalerweise permanent läuft. Gebe ich also die Mappings nicht wieder frei gibt es irgendwann Durcheinander bei den Daten die gelesen werden. Auch schreibt Anwendung [1] einen der Strings in einem festen Interval neu, da sich dieser auch laufend ändert. Hat jemand eine Idee wie man das Problem lösen kann? Gruß |
Re: MemoryMappedFiles - Geht ja gar nicht
Zitat:
|
Re: MemoryMappedFiles - Geht ja gar nicht
Und die Sache, dass nicht alle MMFs ausgelesen werden können? Bzw wann muss ich dann UnmapViewOfFile verwenden? Nach dem Lesen?
|
Re: MemoryMappedFiles - Geht ja gar nicht
UnmapViewOfFile rufst du auf, sobald das Programm (wo gemppt wurde keinen Zugriff mehr braucht ... notfalls kann man ja später nochmals neu mappen.
CloseHandle sobald der Speicher nicht mehr benötigt wird. Solange mindestens eine Anwendung noch zugriff hat, bleibt der Speicher erhalten. Also erst wenn alle Anwendungen den Zugriff per CloseHandle beendet haben (wenn die Anwendung selbst beendet wird, dann schleißt Windows automatisch das zugehörige Handle), dann wird die MMF gelöscht. Kurzfassung ohne Fehlerbehandlung:
Delphi-Quellcode:
function CreateMMF(Filename: PChar; Daten...): THandle;
var Mem: Pointer; begin Result := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, Len, Filename); Mem := MapViewOfFile(hFile, FILE_MAP_WRITE, 0, 0, 0); // hier Daten in MMF kopieren UnmapViewOfFile(Mem); end; procedure CloseMMF(H: THandle); begin CloseHandle(H); end; procedure ReadMMF(Filename: PChar; Daten...); var H: THandle; Mem: Pointer; begin Result := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, Len, Filename); Mem := MapViewOfFile(hFile, FILE_MAP_READ, 0, 0, 0); // hier Daten der MMF auslesen UnmapViewOfFile(Mem); CloseHandle(H); end;
Delphi-Quellcode:
H := CreateMMF(Name, Daten);
// dem anderem Programm mitteilen, das es auszulesen hat und warten bis dieses fertig ist CloseMMF(H); Es geht aber noch schlimmer ... ich arbeite derzeit mit unnamedMMFs und da darf/muß ich jedesmal die Handles umwandeln, damit das andere Programm die MMF überhaupt findet -.-'' |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:42 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz