Sdílet prostřednictvím


Knihovny DLL rozšíření

Rozšiřující DLL knihovna typu MFC je DLL knihovna, která implementuje opakovatelně použitelné třídy odvozené z existujících tříd knihovny Microsoft Foundation Class.

Rozšiřující DLL knihovna typu MFC má následující funkce a požadavky:

  • Spustitelný klient musí být aplikací knihovny MFC, zkompilovanou s definovaným _AFXDLL.

  • Rozšiřující knihovna DLL může být také použita obvyklou DLL knihovnou, která je dynamicky propojená s knihovnou MFC.

  • Rozšiřující knihovny DLL mohou být zkompilovány s definovaným _AFXEXT. To přinutí _AFXDLL také definovat a zajistit, že je získána řádná deklarace ze souborů hlaviček knihovny MFC.To také zajistí, že je definováno AFX_EXT_CLASS jako __declspec(dllexport) při sestavení DLL knihovny, což je nezbytné pokud používáte toto makro k deklarování tříd ve Vaší rozšiřující knihovně DLL.

  • Rozšiřující knihovny DLL nevytvoří instanci odvozené třídy z CWinApp, měly by ale spoléhat na klientskou aplikaci (nebo DLL knihovnu) k poskytnutí tohoto objektu.

  • Rozšiřující knihovny DLL však mohou poskytnout funkci DllMain a provádí zde jakékoliv nezbytné inicializace.

Rozšiřující DLL knihovny jsou vytvořeny použitím dynamické knihovny, verze knihovny MFC (známé také jako sdílená verze knihovny MFC).Pouze spustitelné soubory knihovny MFC (buď aplikacemi nebo obvyklýma knihovnama DLL), které jsou postaveny se sdílenou verzí knihovny MFC, mohou použít rozšířující knihovnou DLL.Klientská aplikace a rozšiřující DLL knihovna musí používat stejnou verzi knihovny MFCx0.dll.S rozšířující knihovnou DLL můžete odvodit nové vlastní třídy z knihovny MFC, a potom nabídnout tuto rozšířující verzi knihovny MFC aplikacím, které volá vaše knihovna DLL.

Rozšířující knihovny DLL lze použít také pro předávání odvozených objektů knihovny MFC mezi aplikací a knihovnou DLL.Členské funkce přidružené s předaným objektem existují v modulu, kde byl objekt vytvořen.Protože jsou tyto funkce exportovány správně při používání sdílené knihovny DLL verze knihovny MFC, můžete volně předat knihovnu MFC nebo objekty ukazatelů odvozené knihovny MFC mezi aplikace a načtené rozšuřující knihovny DLL.

Rozšiřující DLL knihovna typu MFC používá sdílenou verzi knihovny MFC stejným způsobem, jakým používá aplikace sdílenou knihovnu DLL verze knihovny MFC, s několika dalšími důležitými pokyny:

  • Nemá odvozený objekt CWinApp.Musí pracovat s odvozeným objektem CWinApp klientské aplikace. To znamená, že klientská aplikace vlastní hlavní "message pump", nečinnou smyčku a podobně.

  • Zavolá AfxInitExtensionModule v jeho funkci DllMain.Vrácená hodnota této funkce může být zkontrolována.Pokud je vrácena nulová hodnota z AfxInitExtensionModule, vrátí 0 z Vaší funkce DllMain.

  • Vytvoří objekt CDynLinkLibrary při inicializaci, pokud rozšiřující knihovna DLL chce exportovat objekty CRuntimeClass nebo prostředky do aplikace.

Tento typ DLL knihovny byl před verzí 4.0 knihovny MFC nazýván AFXDLL.AFXDLL odkazuje na symbol preprocesoru _AFXDLL, který je definován při vytváření knihovny DLL.

Importy knihoven pro sdílenou verzi knihovny MFC jsou pojmenovány podle zásady, popsané v Zásady vytváření názvů pro knihovny MFC DLL.Visual C++ dodává připravené verze knihoven MFC DLL, navíc dodává knihovny non-MFC DLL, které lze použít a distribuovat s Vašimi aplikacemi.Ty jsou popsány v souboru Redist.txt, který je nainstalován do složky Program Files\Microsoft Visual Studio.

Chcete-li exportovat pomocí .def souboru, umístěte následující kód na začátku a na konci Vašeho souboru hlaviček:

#undef AFX_DATA
#define AFX_DATA AFX_EXT_DATA
// <body of your header file>
#undef AFX_DATA
#define AFX_DATA

Tyto čtyři řádky zajistí, že je Váš kód správně zkompilován pro rozšiřující knihovnu DLL.Odstranění těchto čtyř řádků může způsobit že buď bude Vaše DLL knihovna nesprávně zkompilována nebo nesprávně propojena.

Pokud potřebujete předat ukazatel objektu knihovny MFC nebo ukazatel objektu odvozené knihovny MFC do nebo z knihovny MFC DLL, měla by být DLL knihovna rozšiřující DLL knihovnou.Členské funkce přidružené s předaným objektem existují v modulu, kde byl objekt vytvořen.Protože jsou tyto funkce exportovány správně při používání sdílené knihovny DLL verze knihovny MFC, můžete volně předat knihovnu MFC nebo objekty ukazatelů odvozené knihovny MFC mezi aplikace a načtené rozšuřující knihovny DLL.

Vzhledem k pozměňovacím názvům jazyka C++ a exportním problémům může být exportním seznam rozšiřující DLL knihovny rozdílný mezí ladící a vydanou verzí stejné DLL knihovny a DLL knihoven pro různé platformy.Vydaná verze knihovny MFCx0.dll má přibližně 2 000 exportovaných vstupních bodů; ladící verze knihovny MFCx0D.dll má přibližně 3 000 exportovaných vstupních bodů.

Správa paměti

Knihovna MFCx0.dll a všechny rozšiřující DLL knihovny načtené v adresním prostoru klientské aplikace, používají stejnou přidělenou paměť, načtené prostředky a jiné globální stavy knihovny MFC, jako kdyby byly ve stejné aplikaci.To je důležité, protože knihovny non-MFC DLL a obvyklé DLL knihovny dělají přesný opak a mají každou DLL knihovnu přidělenou mimo svůj vlastní fond paměti.

Pokud rozšiřující DLL knihovna přiděluje paměť, pak může být paměť volně kombinována s přiděleným objektem jiné aplikace.Takže pokud selže aplikace, která je dynamicky propojena s knihovnou MFC, ochrana operačního systému udržuje integritu jakékoliv MFC aplikace, která sdílí DLL knihovnu.

Podobně jiné globální stavy knihovny MFC, jako je aktuální spustitelný soubor, který načítá prostředky, jsou také sdílené mezi klientskou aplikací a všemi rozšiřujícími DLL knihovnami typu MFC, stejně jako knihovna MFCx0.dll.

Sdílení prostředků a tříd

Export prostředků je realizován prostřednictvím seznamu prostředků.Každá aplikace obsahuje jednotlivě propojený seznam objektů CDynLinkLibrary.Při hledání prostředku, pak většina standardních implementací knihovny MFC, které načítají prostředky, nejprve vyhledává v aktuálním modulu prostředků (AfxGetResourceHandle) a v případě, že nebyl prostředek nalezen, přejde seznam objektů CDynLinkLibrary k pokusu načíst požadovaný prostředek.

Procházení seznamem má nevýhody v tom, že je to poněkud pomalejší a vyžaduje to správu rozsahů ID prostředků.Má to výhodu v tom, že klientská aplikace, která je propojena s několika rozšiřujícími DLL knihovnami, může použít jakýkoliv prostředek, poskytnutý DLL knihovoun, aniž by bylo nutné určit popisovač instance knihovny DLL.AfxFindResourceHandle je rozhraní API, použité pro procházení seznamu prostředků pro nalezení odpovídající shody.Přebírá název a typ prostředku a vrací popisovač prostředku, který byl nalezen první (nebo hodnotu NULL).

Pokud nechcete procházet seznam a chcete pouze načíst prostředky z konkrétního místa, použíjte funkce AfxGetResourceHandle a AfxSetResourceHandle pro uložení starého popisovače a nastavení nového popisovače.Nezapomeňte obnovit starý popisovač prostředku před jeho vrácením do klientské aplikace.Příklad použití tohoto přístupu s explicitním načtením nabídky naleznete v souboru Testdll2.cpp v příkladu MFC knihovny DLLHUSK.

Dynamické vytvoření objektů knihovny MFC přidělí název knihovny MFC je podobné.Mechanismus deserializace objektu knihovny MFC potřebuje mít všechny registrované objekty CRuntimeClass tak, aby jej mohl obnovit dynamickým vytvořením objektů jazyka C++ z požadovaného typu, založeném na tom, co bylo uloženo dříve.

Pokud se jedná o příklad knihovny MFC DLLHUSK, vypadá seznam podobně jako:

head ->   DLLHUSK.EXE   - or -   DLLHUSK.EXE
               |                      |
          TESTDLL2.DLL           TESTDLL2.DLL
               |                      |
          TESTDLL1.DLL           TESTDLL1.DLL
               |                      |
           MFCOxxD.DLL                |
               |                      |
           MFCDxxD.DLL                |
               |                      |
            MFCxxD.DLL            MFCxx.DLL

kde xx je číslo verze; například 42 představuje verze 4.2.

Knihovna MFCxx.dll je obvykle poslední v seznamu prostředků a v seznamu tříd.Knihovna MFCxx.dll zahrnuje všechny standardní prostředky knihovny MFC, včetně řetězců pro všechny standartní ID příkazy.Jeho umístěním na konci seznamu umožňuje rozšiřující knihovně DLL a klientské aplikaci nemít svou vlastní kopii standartních prostředků knihovny MFC, ale místo toho se spoléhají na sdílené prostředky v MFCxx.dll.

Sloučení prostředků a názvů tříd všech knihoven DLL do jmenného prostoru klientské aplikace má nevýhodu ve vyžadování Vaší opatrnosti v tom, které ID nebo názvy vyberete.

Příklad DLLHUSK pravuje jménný prostor sdílených prostředků použitím více hlavičkových souborů.

Pokud potřebuje Vaše rozšiřující DLL knihovna typu MFC spravovat navíc data pro každou aplikaci, můžete odvodit novou třídu z CDynLinkLibrary a vytvořit jí v DllMain. Je-li spuštěna, může knihovna DLL zkontrolovat seznam aktuální aplikace objektu CDynLinkLibrary k nalezení jedné konkrétní rozšiřující DLL knihovny.

h5f7ck28.collapse_all(cs-cz,VS.110).gifCo chcete udělat?

h5f7ck28.collapse_all(cs-cz,VS.110).gifCo chcete vědět více?

Viz také

Koncepty

Knihovny DLL jazyka Visual C++