Sdílení paměti pomocí mapování souborů (2. díl) - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



Delphi

Sdílení paměti pomocí mapování souborů (2. díl)

sdileni pameti

5. srpna 2002, 00.00 | Dnes začneme psát serverovou část ukázkové aplikace, na které si téma file mappingu blíže ukážeme.

Opakování

Nejdřív malé opakování z minulého dílu: Dověděli jste se, co to je file mapping a že je možné ho výhodně použít ke sdílení části paměti mezi více programy, což normálně ve Windows nejde. Slíbil jsem, že si vše ukážeme na příkladu typu klient-server: V jednoduchém textovém editoru (server) bude uživatel psát text, který se bude zobrazovat v oknech klientů, kterých budete možno spustit libovolně mnoho. Uznávám, že praktická hodnota zvoleného příkladu je nulová, ale vcelku dobře si na něm vysvětlíme vše podstatné okolo API file mappingu.

K ukázkové aplikaci bych ještě dodal, že kvůli přehlednosti kódu prakticky nikde neošetřuji chyby - především nezkoumám návratové hodnoty volaných API funkcí. Pokud byte chtěli mapovaní souborů použít v "opravdových" programech, důrazně doporučuji nebýt líný a možné chyby důsledně ošetřit.

Serverová část aplikace

Dnes se podíváme na serverovou část aplikace. Oproti svým zvyklostem budu tentokrát nejdříve uvádět výpisy kódu a až pak vysvětlovat, co přesně dělají. Jak serverová část vypadá se můžete podívat na obrázku - není to nic světoborného, obyčejný formulář s komponentou TMemo.

Ukázková aplikace - server

První část kódu by měla přijít někam na začátek souboru s hlavním formulářem:

var
  HMessage: THandle;
  HMap: THandle;

const
  MsgId = 'MappingBroadcastMessage';
  MappingId = 'TestMapping';

Deklarujeme dvě pomocné proměnné a konstanty, vysvětlení jejích účelu se dobereme později. Obě proměnné by se samozřejmě daly deklarovat i jako pole formuláře (například v sekci private) - to je ale nepodstatný detail, který nehraje v tomto případě roli.

procedure TMainForm.FormCreate(Sender: TObject);
begin
  HMessage := RegisterWindowMessage(MsgId);
  HMap:= CreateFileMapping($FFFFFFFF, nil,
    PAGE_READWRITE, 0, 32 * 1024, MappingId);
end;

Při spuštění aplikace je nejdříve zavolána funkce RegisterWindowMessage. Rozhodl jsem se totiž klienty informovat o změnách textu zasláním zprávy (message), což je standardní způsob jak takovou situaci ve Windows řešit. Vzhledem k tomu, že požadujeme, aby klientů mohlo být víc, musíme zajistit, aby se zpráva dostala ke všem. Mohli bychom si udržovat jejich seznam, to by ale věc zkomplikovalo. Proto pošleme zprávu všem oknům ve Windows, ať si ji přeberou, jak umí. Musíme ale vyloučit aby na ní reagovaly ostatní okna - potřebujeme tedy identifikátor zprávy, který je systémově jedinečný a zaručeně není nikým jiným využíván. To právě zajistí funkce RegisterWindowMessage. Za jediný parametr si bere název zprávy jako řetězec a za výsledek vydá identifikátor zprávy, jednoznačný v celém systému. Pokud zavoláme RegisterWindowMessage z různých aplikací se stejným parametrem, výsledek bude vždy stejný. Proto ji budeme volat i v klientské aplikaci a tím pádem se obě části dohodnou na svém identifikátoru zprávy, který budou používat pro oznámení o změnách textu v okně serveru.

Funkce CreateFileMapping je zodpovědná za namapování souboru do paměti. Její první parametr je handle otevřeného souboru, který se má namapovat. Zde používáme speciální hodnotu $FFFFFFFF, která namapuje virtuální (fyzicky na disku neexistující) soubor - bližší vysvětlení najdete v minulém dílu.

Druhý parametr (na Windows 9x/ME ignorovaný) jsou bezpečnostní atributy - hodnota nil znamená použít výchozí, což nám postačí. Dalším parametrem určujeme, zda je souboru určen ke čtení (PAGE_READONLY) nebo i zápisu (PAGE_READWRITE). Možných je i několik dalších hodnot, pro jejich popis vás ale už odkážu do nápovědy Win32 API.

Další dva parametry určují maximální velikosti souboru (vyšší a nižší část tvořící dohromady 64bitové číslo). Zde nám postačuje 32 kB, protože větší délku textu stejně TMemo nepodporuje.

Zbylý poslední parametr je řetězec identifikující mapování. Jak už možná tušte, účel je podobný jako u RegisterWindowMessage - když v klientovi použijeme stejnou hodnotu, obdržíme namapovaný stejný soubor. Oproti RegisterWindowMessage je tu ale několik drobných rozdílů, ty si však osvětlíme až v dílu věnovaném klientské části aplikace.

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  CloseHandle(HMap);
end;

Procedura TMainForm.FormDestroy jen zavře otevřený handle k mapování souboru.

Příště

V příští části seriálu si file mapping dovysvětlíme a serverovou aplikaci dokončíme. Abyste měli představu, jak bude výsledek vypadat, můžete si obě části aplikace stáhnout, samozřejmě i se zdrojovými kódy (Delphi 3 a vyšší).

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Delphi  

 » Rubriky  » Windows  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: