[ Pobierz całość w formacie PDF ]
.Taki stan rzeczypowodowa³, ¿e biblioteki DLL stanowi³y naturalny obszar wymiany danych miêdzyaplikacjami i — niestety — równie¿ arenê niepo¿¹danych interferencji, coprojektanci zawsze musieli braæ pod uwagê.Wyjaœnialiœmy ju¿ wczeœniej zasady wykorzystywania bibliotek DLL w Win32 — wwarunkach, gdy ka¿da biblioteka DLL istnieje wy³¹cznie pod postaci¹ swoichinstancji w przestrzeniach adresowych poszczególnych procesów; wobecroz³¹cznoœci tych przestrzeni, tradycyjna technika rodem z Windows 3.x na nicsiê w tym wypadku nie przyda.Nie oznacza to bynajmniej, i¿ komunikacja dwóch aplikacji przez tê sam¹bibliotekê DLL jest zupe³nie niemo¿liwa; nadal mo¿liwe jest komunikowanie siêprzez obszar danych biblioteki DLL (co mo¿e byæ przydatne przy przenoszeniuaplikacji 16-bitowych do Delphi 6), realizowane jest jednak za pomoc¹ zupe³nieinnych œrodków — mianowicie mechanizmu plików odwzorowanych, który opisaliœmyze szczegó³ami na stronach 580 – 598 ksi¹¿ki „Delphi 4.Vademecumprofesjonalisty”.W tym miejscu ograniczymy siê tylko do jego wybranychelementów.Tworzenie bibliotek DLL z pamiêci¹ dzielon¹Poni¿szy wydruk przedstawia plik projektu biblioteki ShareLib.dll, zawieraj¹cykod, który umo¿liwia wspó³dzielenie obszaru danych tej biblioteki.Obszar tenwskazywany jest przez zmienn¹ o nazwie GlobalData.Wydruk 6.12.Biblioteka DLL umo¿liwiaj¹ca wspó³dzielenie swego obszaru danychprzez ró¿ne procesylibrary ShareLib;usesShareMem,Windows,SysUtils,Classes;constcMMFileName: PChar = 'SharedMapData';{$I DLLDATA.INC}varGlobalData : PGlobalDLLData;MapHandle : THandle;{ fnkcja importowana z biblioteki DLL }procedure GetDLLData(var AGlobalData: PGlobalDLLData); StdCall;begin{ pobierz wskazanie na obszar danych globalnych biblioteki }AGlobalData := GlobalData;end;procedure OpenSharedData;varSize: Integer;begin{ pobierz rozmiar mapowanych danych }Size := SizeOf(TGlobalDLLData);{ Stwórz obiekt mapuj¹cy; zwróæ uwagê, i¿ zamiast uchwytu odwzorowywanegopliku wystêpuje $FFFFFFFF co oznacza, i¿ plik ten nie bêdzie widoczny nazewn¹trzpod konkretn¹ nazw¹, lecz stanowi³ bêdzie fragment pliku wymiany.Wymaga to, by obiekt mapuj¹cy posiada³ unikatow¹ nazwê}MapHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, Size,cMMFileName);if MapHandle = 0thenRaiseLastWin32Error;{ dokonaj mapowania w obszar pamiêci i przypisz adres tego obszarudo zmiennej GlobalData}GlobalData := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, Size);{ Zainicjuj dane globalne jak¹œ zawartoœci¹ }GlobalData^.S := 'ShareLib';GlobalData^.I := 1;if GlobalData = nil thenbeginCloseHandle(MapHandle);RaiseLastWin32Error;end;end;procedure CloseSharedData;{ zwolnij obszar pamiêci odwzorowuj¹cy zawartoœæ plikui obiekt mapuj¹cy}beginUnmapViewOfFile(GlobalData);CloseHandle(MapHandle);end;procedure DLLEntryPoint(dwReason: DWord);begincase dwReason ofDLL_PROCESS_ATTACH: OpenSharedData;DLL_PROCESS_DETACH: CloseSharedData;end;end;exportsGetDLLData;begin{ przypisz procedurê inicjuj¹co-koñcz¹c¹ }DllProc := @DLLEntryPoint;DLLEntryPoint(DLL_PROCESS_ATTACH);end.Wspó³dzielone dane posiadaj¹ nastêpuj¹c¹ strukturê, zdefiniowan¹ w do³¹czonympliku DLLDATA.INC:PGlobalDLLData = ^TGlobalDLLData;TGlobalDLLData = recordS: String[50];I: Integer;end;Kod biblioteki wykorzystuje mechanizm procedury inicjuj¹co-koñcz¹cej; za jejpoœrednictwem wywo³ywane s¹ dwie procedury: OpenSharedData() (przyrozpoczynaniu programu) oraz CloseSharedData() (przy jego koñczeniu).Mechanizm plików odwzorowanych umo¿liwia — mówi¹c ogólnie — zarezerwowanieregionu w wirtualnej przestrzeni adresowej Win32 i zwi¹zanie z nimrzeczywistego fragmentu pamiêci fizycznej
[ Pobierz całość w formacie PDF ]