TN011: Použití prostředí MFC jako součásti knihovny DLL
Tato poznámka popisuje běžné knihovny DLL, které umožňují použití knihovny MFC jako součást systému Windows dynamickou knihovnu (DLL).Předpokládá, že jste obeznámeni s knihoven DLL systému Windows a postup jejich vytvoření.Informace o rozšíření knihoven DLL MFC, pomocí kterého můžete vytvořit rozšíření knihovny MFC naleznete v tématu DLL verze knihovny MFC.
Knihovny DLL rozhraní
Běžné knihovny DLL se předpokládá rozhraní mezi aplikací a DLL jsou specifikovány v C podobné funkce nebo explicitně exportované třídy.Rozhraní MFC třídy nelze exportovat.
Pokud chcete použít knihovnu MFC DLL a aplikace, mají možnost použít sdílenou verzi knihovny MFC nebo staticky propojíte kopii knihovny.Aplikace a DLL může i některým standardní verzí knihovny MFC.
Běžné knihovny DLL mají několik výhod:
Aplikace, používající DLL není nutné použít knihovnu MFC a nemusí být aplikace Visual C++.
S obvyklým DLL knihovnám, které jsou staticky propojeny ke knihovně MFC velikost souboru DLL závisí pouze na rutin runtime knihovny MFC a C, které jsou používány a jsou propojeny.
S obvyklým DLL knihovnám, které jsou dynamicky propojené ke knihovně MFC mohou být významné úspory v paměti pomocí sdílenou verzi knihovny MFC.Nicméně, je nutné distribuovat sdílené knihovny DLL Mfc<version>DLL a Msvvcrt<version>DLL s knihovnou DLL.
DLL je nezávislé na způsobu implementace třídy.Návrh knihovny DLL exportuje pouze rozhraní API, které chcete.Výsledkem je pokud se změní implementaci, běžné knihovny DLL jsou stále platná.
S obvyklým DLL knihovnám, které jsou staticky propojeny ke knihovně MFC používáte-li knihovny DLL a aplikace knihovny MFC, nebyly zaznamenány žádné problémy s aplikací, která požaduje jinou verzi knihovny MFC knihovny DLL nebo naopak.Vzhledem k tomu, že knihovna MFC je staticky propojena do každé knihovny DLL nebo EXE, není žádná otázka, jakou verzi máte.
Omezení rozhraní API
Některé funkce knihovny MFC se nevztahuje na knihovnu DLL verze, buď z důvodu technických omezení, nebo proto, že tyto služby jsou obvykle poskytovány aplikací.V aktuální verzi knihovny MFC je pouze funkce, která není k dispozici CWinApp::SetDialogBkColor.
Sestavování vaší knihovny DLL
Při sestavování obvyklé knihovny DLL, které jsou staticky propojeny ke knihovně MFC, symboly _USRDLL a _WINDLL musí být definovány.Váš kód knihovny DLL musí být také kompilována s následující přepínače kompilátoru:
/D_WINDLLOznačuje, že sestavení je pro knihovnu DLL
/D_USRDLLUrčuje, že vytváříte běžné knihovny DLL
Také musíte definovat tyto symboly a použít tyto parametry kompilátoru při kompilaci běžných DLL knihovnách, které jsou dynamicky propojené ke knihovně MFC.Navíc symbol _AFXDLL musí být definovány a váš kód knihovny DLL musí být kompilována s:
- /D_AFXDLLUrčuje, že vytváříte běžné knihovny DLL, která dynamicky propojuje ke knihovně MFC
Rozhraní (API) mezi aplikací a DLL Knihovny musí být explicitně exportovány.Doporučujeme definovat vaše rozhraní jako malou šířkou pásma a použití pouze C rozhraní, pokud je to možné.Přímé rozhraní C je snadnější než složitější třídy jazyka C++.
Místo v rozhraní API v samostatné záhlaví, které mohou obsahovat soubory C a C++.Zobrazeno záhlaví ScreenCap.h v ukázce knihovny MFC Upřesnit pojmy DLLScreenCap příklad.Chcete-li exportovat funkce, zadejte je v EXPORTS v části soubor definice modulu (.DEF) nebo __declspec(dllexport) na vaše definice funkce.Použití __declspec(dllimport) k importu těchto funkcí do klientského spustitelného souboru.
Je nutné přidat AFX_MANAGE_STATE makro na začátku všech exportovaných funkcí v běžných DLL knihovnách, které jsou dynamicky propojené ke knihovně MFC.Toto makro nastaví aktuální stav modulu na jeden z knihovny DLL.Chcete-li použít toto makro, přidejte následující řádek kódu na začátek exportované funkce z knihovny DLL:
AFX_MANAGE_STATE(AfxGetStaticModuleState( ))
WinMain -> DllMain
Knihovna MFC definuje standardní Win32 DllMain vstupní bod, který inicializuje své CWinApp odvozený objekt jako typické aplikaci knihovny MFC.Umístěte všechny inicializace specifické DLL Knihovny v InitInstance metoda jako typické aplikaci knihovny MFC.
Všimněte si, protože mechanismus CWinApp::Run se nevztahuje na knihovnu DLL, aplikace vlastní hlavní "message pump". Pokud vaše knihovna DLL zobrazí nemodální dialogová okna nebo má své vlastní okno rámce, hlavní, musí hlavní "message pump" vaší aplikace zavolat rutinu exportované DLL Knihovny, která volá CWinApp::PreTranslateMessage.
Prohlédněte ukázku DLLScreenCap pro použití této funkce.
DllMain Funkce, která knihovna MFC poskytuje bude volat CWinApp::ExitInstance metoda třídy, která je odvozená od CWinApp dříve, než je knihovna DLL uvolněna.
Propojování vaší knihovny DLL
S obvyklým DLL knihovnám, které jsou staticky propojeny ke knihovně MFC je nutné propojit knihovnu DLL s Nafxcwd.lib nebo Nafxcw.lib a verze runtimes C, s názvem Libcmt.lib.Tyto knihovny jsou předem připravené a může být instalován zadáním je při spuštění instalačního programu Visual C++.
Ukázka kódu
Naleznete v ukázce knihovny MFC pokročilé koncepty programu úplnou ukázku DLLScreenCap.Poznámka: v této ukázce několik zajímavých věcí jsou následující:
Příznaky kompilátoru DLL knihovny a aplikace se liší.
Čáry vazeb a.DEF souborů pro knihovnu DLL a ty aplikace se liší.
Aplikace, používající DLL nemusí být v jazyce C++.
Rozhraní mezi aplikací a DLL je rozhraní API, které je možné použít v C nebo C++ a je vyvezeno s DLLScreenCap.def.
Následující příklad ukazuje rozhraní API, které je definováno v běžné knihovně DLL, která staticky propojuje ke knihovně MFC.V tomto příkladu je součástí prohlášení extern "C" { } blok pro uživatele jazyka C++.To má několik výhod.Nejprve je vaše knihovna DLL rozhraní API použitelné bez C++ klientské aplikace.Druhý zmenšuje režii DLL, protože úprava názvu C++ se neuplatní na exportovaný název.Nakonec ji usnadňuje explicitně přidat.DEF souborů (pro export podle pořadí) bez starosti o pozměnění název.
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct TracerData
{
BOOL bEnabled;
UINT flags;
};
BOOL PromptTraceFlags(TracerData FAR* lpData);
#ifdef __cplusplus
}
#endif
Struktury používané rozhraním API nejsou odvozeny od tříd knihovny MFC a jsou definovány v rozhraní API záhlaví.To snižuje složitost rozhraní mezi knihovnou DLL a aplikací a umožňuje použít knihovny DLL C programy.