Thema: Delphi WM_COPYDATA mit arrays?

Einzelnen Beitrag anzeigen

Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.648 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: WM_COPYDATA mit arrays?

  Alt 20. Mai 2010, 08:22
Und was MMFs angeht: Die habe ich zum Datenaustausch hier in diesem Projekt auch benutzt:
http://www.delphipraxis.net/internal....php?p=1071944
Dort habe ich die Größe per Parameter an eine neue Instanz übergeben, du kannst hier ja einfach Messages benutzen, das macht es noch einfacher. Der Quelltext ist auch relativ kurz.

Dies sind die relevanten Teile des Codes:
Delphi-Quellcode:
// ab Zeile 453:
    FMMFFileHandle := CreateFileMapping(INVALID_HANDLE_VALUE, nil,
      PAGE_READWRITE, 0, FileListStream.Size, MmfCommunicationName);
    // Handle will be closed in our destructor
    if FMMFFileHandle <> 0 then
    begin
      MMFPointer := MapViewOfFile(FMMFFileHandle, FILE_MAP_WRITE, 0, 0,
        FileListStream.Size);
      FileListStream.Position := 0;
      CopyMemory(MMFPointer, FileListStream.Memory, FileListStream.Size);
      UnmapViewOfFile(MMFPointer);
Ich erzeuge also eine neue MMF mit der Größe des Streams FileListStream. Dann setze ich den View entsprechend und kopiere die Daten hinein, fertig. Jetzt übergebe ich diese Größe (bei mir als Parameter) an den zweiten Prozess.

Dort öffne ich dann die MMF:
Delphi-Quellcode:
// ab Zeile 512:
var
  HandleCount: Integer;
  MMFPointer: Pointer;
  MMFFileHandle: THandle;
begin
  MMFFileHandle := OpenFileMapping(FILE_MAP_READ, True, MmfCommunicationName);
  if AStep2 then // only here we have to wait for the mutex to ensure the file mapping is open
    CreateMutex(nil, False, PChar(UpdateNotifyMutexName));
  if MMFFileHandle <> 0 then
  begin
    MMFPointer := MapViewOfFile(MMFFileHandle, FILE_MAP_READ, 0, 0, 0);
Hier öffne ich einfach mit Offset und Größe 0, so dass die gesamte MMF gemappt wird. Du musst die Größe also gar nicht angeben. Wenn du zum Beispiel am Anfang immer einen Integerwert mit der Größe usw. als Header speicherst, dann reicht das bereits zum Auslesen. Den bekommst du dann mit PInteger(Integer(MMFPointer))^ ausgelesen.

Das sieht bei mir in den folgenden Zeilen so aus um den Integer am Ende des Mappings auszulesen und dann einen Teil der Daten zu kopieren, aber das ist für dich nicht weiter wichtig:
Delphi-Quellcode:
    // Read update list, size is 4 byte less than in AListStreamSize, because we
    // have an integer with the count of handles at the end.
    HandleCount := PInteger(Integer(MMFPointer) + AListStreamSize - SizeOf(HandleCount))^;
    AFileListStream.Size := AListStreamSize - HandleCount * SizeOf(THandle) - SizeOf(HandleCount);
    CopyMemory(AFileListStream.Memory, MMFPointer, AFileListStream.Size);
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat