c ++ - Brug af delt hukommelse under Windows. Sådan passerer du forskellige data

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg forsøger i øjeblikket at gennemføre nogle interprocess kommunikation ved hjælp af Windows CreateFileMapping mekanismen. Jeg ved, at jeg skal oprette et filmappeobjekt med CreateFileMapping først og derefter oprette en pointer til de faktiske data med MapViewOfFile. Eksemplet sætter derefter data i mapfilen ved hjælp af CopyMemory. [14]


I min ansøgning har jeg en billedbuffer (1 MB stor), som jeg vil sende til en anden proces. Så nu spørger jeg en peger på billedet og kopierer derefter hele billedbufferen til kortfilen. Men jeg spekulerer på, om dette virkelig er nødvendigt. Er det ikke muligt at kopiere en faktisk pointer i den delte hukommelse, der peger på billedbufferdata? Jeg forsøgte lidt, men lykkedes ikke.

Bedste reference


Forskellige processer har forskellige adresselokaler. Hvis du sender en gyldig pointer i en proces til en anden proces, vil det sandsynligvis pege på tilfældige data i den anden proces. Så du bliver nødt til at kopiere alle dataene.

Andre referencer 1


Jeg stærkt anbefaler at du bruger Boost :: interprocess. Det har masser af godbidder at styre denne slags ting & selv indeholder nogle specielle Windows-only-funktioner, hvis du skal interoperere med andre processer, der bruger bestemte Win32-funktioner. [15]


Det vigtigste er at bruge offsetpegere i stedet for regelmæssige peger. Offset pointers er grundlæggende relative pointers (de gemmer forskellen mellem hvor markøren er og hvor sagen peger på). Det betyder, at selvom de to pegepunkter er kortlagt til forskellige adresselokaler, så længe mapperne er ens i strukturen, så har du det fint. [16]


Jeg har brugt alle former for komplicerede datastrukturer med offset smart pointers, og det fungerede som en charme.

Andre referencer 2


Shared Memory betyder ikke at sende og modtage data. Det er en hukommelse, der er oprettet til antallet af processer uden overtrædelse. Dermed skal du følge nogle mekanismer som lås, så dataene ikke korrumperer.


I proces 1:


CreateFileMapping(): Den vil oprette den delte hukommelsesblok med navnet angivet i den sidste parameter, hvis den ikke allerede er til stede og vender tilbage til et håndtag (du kan kalde det en pointer), hvis det lykkes.


MapViewOfFile(): Det kortlægger (indeholder) denne delte blok i procesadressens rum og returnerer et håndtag (igen kan du sige en pointer).


Med denne pointer returneret af MapViewOfFile() kan du kun få adgang til den delte blok.


I proces 2:


OpenFileMapping(): Hvis den delte hukommelsesblok er oprettet med CreateFileMapping(), kan du bruge den med samme navn (navn der bruges til at oprette den delte hukommelsesblok).


UnmapViewOfFile(): Det vil afkorte (du kan fjerne den delte hukommelsesblok fra den procesadresse). Når du er færdig med den delte hukommelse (dvs. adgang, modifikation osv.), Skal du ringe til denne funktion.


Closehandle(): Til sidst at fjerne den delte hukommelsesblok fra processen, kald dette med argument, håndteret returneret af OpenFileMapping () eller CreateFileMapping ().


Selvom disse funktioner ser enkle ud, er opførslen vanskelig hvis flagene ikke vælges korrekt.
Hvis du ønsker at læse eller skrive delt hukommelse, skal du angive PAGE\_EXECUTE\_READWRITE i CreateFileMapping().


Når du ønsker at få adgang til delt hukommelse efter at have oprettet det med succes, skal du bruge FILE\_MAP\_ALL\_ACCESS i MapViewOfFile().


Det er bedre at angive FALSE (ikke arve håndtere fra forældreprocessen) i OpenFileMapping(), da det vil undgå forvirring.

Andre referencer 3


Du CAN får delt hukommelse til at bruge samme adresse over 2 processer til Windows. Det er muligt med flere teknikker.


Brug af MapViewOfFileEx, her er den betydelige erfaring fra MSDN. [17]



  Hvis en foreslået kortlægningsadresse er
  leveres, filen er kortlagt på
  angivne adresse (afrundet til
  nærmeste 64K-grænse), hvis der er
  tilstrækkeligt adresserum til det angivne
  adresse. Hvis der ikke er nok
  adresserummet, fejler funktionen.

  
  Den foreslåede adresse er typisk
  bruges til at angive, at en fil skal være
  kortlagt på samme adresse i flere
  processer. Dette kræver regionen
  adresserummet er tilgængeligt for alle
  involverede processer. Ingen anden hukommelse
  tildeling kan finde sted i
  region, der bruges til kortlægning,
  herunder brugen af ​​VirtualAlloc
  eller VirtualAllocEx funktion til at reservere
  hukommelse.

  
  Hvis parameteren lpBaseAddress
  angiver en basisforskydning, funktionen
  lykkes hvis den angivne hukommelse
  regionen er ikke allerede i brug af
  opkaldsproces. Systemet gør det ikke
  sørg for, at det samme hukommelsesområde er
  tilgængelig for den hukommelseskartede fil
  i andre 32-bit-processer.



En anden relateret teknik er at bruge en DLL med et afsnit mærket Læs + Skriv + Delt. I dette tilfælde vil OS stort set gøre MapViewOfFileEx-opkaldet til dig og til enhver anden proces, som indlæser DLL'en.


Du skal muligvis markere din DLL til en FIXED belastningsadresse, ikke flytbar osv. Naturligt.

Andre referencer 4


Du kan bruge Marshalling of pointers.

Andre referencer 5


Hvis det er muligt, ville det være bedst at få billeddataene indlæst/genereret direkte i det delte hukommelsesområde. Dette eliminerer hukommelseskopien og sætter den direkte, hvor den skal være. Når den er klar, kan du signalere den anden proces, hvilket giver det udligningen i din delte hukommelse, hvor dataene begynder.