Biblioteki ładowane dynamicznie DLL
Transkrypt
Biblioteki ładowane dynamicznie DLL
MICROSOFT FOUNDATION CLASSES BIBLIOTEKI ŁADOWANE DYNAMICZNIE DLL REGULAR DLL WITH MFC STATICALLY LINKED REGULAR DLL USING SHARED MFC DLL Biblioteki tego typu mogą być wykorzystywane przez programy nie napisane w MFC. Biblioteki stosujące statyczne linkowanie MFC mogą być nawet używane w systemach, gdzie MFC w ogóle nie jest zainstalowane. Druga odmiana wymaga obecności w systemie DLL-i MFC, za to rozmiary plików tych bibliotek są zdecydowanie mniejsze. Tworząc funkcje warto przestrzegać następujących zasad: 1. Stosujemy funkcje C, a nie C++ (extern “C”). Unikamy w ten sposób udekorowanych nazw C++. Dzięki temu łatwo będzie skorzystać z DLL w programach pisanych w językach innych, niż C++. 2. Eksportujemy raczej funkcje, nie całe klasy – z tych samych, co powyżej, przyczyn. 3. Funkcje eksportowane opatrujemy przedrostkiem __declspec(dllexport). 4. Nagłówki funkcje przeznaczonych do importowania przez inne moduły opatrujemy przedrostkiem __declspec(dllimport). Punkty (1) i (2) możemy zignorować, jeśli biblioteki mają być stosowane wyłącznie przez programistów C++. Punkty (3) i (4) możemy zignorować wprowadzając odpowiednie zapisy do pliku DEF. Oto przykładowy, prosty plik nagłówkowy biblioteki: #ifdef __cplusplus extern "C" { #endif __declspec(dllimport) void ShowMsg(char *p); #ifdef __cplusplus } #endif Uwaga! Biblioteki tego typu zawierają obiekt klasy CWinApp (każdy moduł MFC musi zawierać taki obiekt) – jest to warunkiem korzystania z funkcji MFC. W przypadku korzystania z MFC.DLL niezbędne jest ustalenie kontekstu wywołania w obrębie MFC przy każdym wywołaniu funkcji, która korzystać będzie z mechanizmów MFC. Przykładowa funkcja przybiera więc postać: __declspec(dllexport) void ShowMsg(char *p) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); AfxMessageBox(p); } // obowiązkowe w DLL używającym MFC DLL MFC EXTENSION DLL (USING SHARED MFC DLL) Biblioteki tego typu mogą być używane wyłącznie przez programy korzystające z MFC, za to można eksportować – i na ogół się to robi – klasy wywiedzione z klas bazowych MFC (stąd nazwa extension dll). DLL tego typu współdzieli z wywoływaną aplikacją obiekt aplikacji i zasoby; obydwa moduły mogą współużytkować dowolne obiekty MFC. Nie ma potrzeby stosowania extern "C"; wygodnie jest natomiast stosować przedrostki __declspec(dllimport) i __declspec(dllexport), szczególnie, że można je umieszczać w nagłówkach klas! Przydatne jest standardowe makro AFX_EXT_CLASS, które pozwala stosować ten sam nagłówek do eksportowania klas i funkcji z DLL, jak i importowania przez inne moduły. Jest ono zdefiniowane mniej więcej tak: #ifdef _AFXDLL #define AFX_EXT_CLASS #else #define AFX_EXT_CLASS #endif __declspec(dllexport) __declspec(dllimport)