Sdílet prostřednictvím


Rozšiřující knihovny MFC DLL

Knihovna DLL rozšíření MFC je knihovna DLL, která obvykle implementuje opakovaně použitelné třídy odvozené z existujících tříd knihovny tříd Microsoft Foundation.

Knihovna DLL rozšíření MFC má následující funkce a požadavky:

  • Spustitelný soubor klienta musí být aplikace MFC zkompilovaná s definovaným souborem _AFXDLL .

  • Knihovnu DLL rozšíření MFC lze také použít běžnou knihovnou MFC DLL, která je dynamicky propojena s knihovnou MFC.

  • Knihovny DLL rozšíření MFC by se měly zkompilovat s definovanými definicemi _AFXEXT . To vynutí _AFXDLL také definovat a zajistit, že správné deklarace se načte ze souborů hlaviček MFC. Také zajišťuje, že AFX_EXT_CLASS je definován jako __declspec(dllexport) při sestavování knihovny DLL, což je nutné, pokud používáte toto makro deklarovat třídy v rozšiřující knihovně DLL knihovny MFC.

  • Knihovny DLL rozšíření MFC by neměly vytvořit instanci třídy odvozené z CWinApp, ale měly by spoléhat na klientskou aplikaci (nebo knihovnu DLL) poskytnout tento objekt.

  • Knihovny DLL rozšíření MFC by však měly poskytovat funkci a provádět v ní veškerou DllMain potřebnou inicializaci.

Knihovny DLL rozšíření se sestavují pomocí verze knihovny MFC s dynamickým propojením (označované také jako sdílená verze knihovny MFC). Knihovny DLL rozšíření MFC můžou používat pouze spustitelné soubory MFC (aplikace nebo běžné knihovny MFC DLL), které jsou vytvořené ve sdílené verzi knihovny MFC. Klientská aplikace i knihovna DLL rozšíření MFC musí používat stejnou verzi MFCx0.dll. Pomocí knihovny DLL rozšíření MFC můžete odvodit nové vlastní třídy z knihovny MFC a pak nabídnout tuto rozšířenou verzi knihovny MFC aplikacím, které volají vaši knihovnu DLL.

Rozšiřující knihovny DLL lze použít také k předávání objektů odvozených z knihovny MFC mezi aplikací a knihovnou DLL. Členské funkce přidružené k předaným objektu existují v modulu, ve kterém byl objekt vytvořen. Vzhledem k tomu, že se tyto funkce správně exportují při použití sdílené verze knihovny MFC knihovny MFC, můžete volně předat ukazatele objektů odvozené od MFC mezi aplikací a rozšiřující knihovny MFC DLL, které načte.

Knihovna DLL rozšíření MFC používá sdílenou verzi knihovny MFC stejným způsobem, jakou aplikace používá sdílenou verzi knihovny MFC, s několika dalšími aspekty:

  • Nemá -odvozený CWinAppobjekt. Musí pracovat s -odvozeným CWinAppobjektem klientské aplikace. To znamená, že klientská aplikace vlastní hlavní čerpadlo zpráv, nečinnou smyčku atd.

  • AfxInitExtensionModule Volá ve své DllMain funkci. Vrácená hodnota této funkce by měla být zkontrolována. Pokud se vrátí nulová hodnota, AfxInitExtensionModulevrátí hodnotu 0 z funkce DllMain .

  • Při inicializaci vytvoří objekt CDynLinkLibrary , pokud knihovna DLL rozšíření MFC chce exportovat CRuntimeClass objekty nebo prostředky do aplikace.

Před verzí 4.0 knihovny MFC se tento typ knihovny DLL nazývá AFXDLL. AFXDLL odkazuje na symbol preprocesoru _AFXDLL , který je definován při sestavování knihovny DLL.

Knihovny importu pro sdílenou verzi knihovny MFC jsou pojmenovány podle konvence popsané v konvencích pojmenování knihoven MFC DLL. Visual Studio poskytuje předem sestavené verze knihoven MFC DLL a řadu knihoven DLL jiných než MFC, které můžete používat a distribuovat s aplikacemi. Jsou zdokumentované v souboru Redist.txt, který je nainstalován do složky Program Files\Microsoft Visual Studio.

Pokud exportujete pomocí souboru .def, umístěte následující kód na začátek a konec hlavičkového souboru:

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

Tyto čtyři řádky zajišťují, aby byl kód správně zkompilován pro knihovnu DLL rozšíření MFC. Vynechání těchto čtyř řádků může způsobit, že se knihovna DLL zkompiluje nebo nesprávně propojí.

Pokud potřebujete předat ukazatel objektu odvozeného z MFC nebo MFC do knihovny MFC DLL, měla by být knihovna DLL rozšíření KNIHOVNY MFC. Členské funkce přidružené k předaným objektu existují v modulu, ve kterém byl objekt vytvořen. Vzhledem k tomu, že se tyto funkce správně exportují při použití sdílené verze knihovny MFC knihovny MFC, můžete volně předat ukazatele objektů odvozené od MFC mezi aplikací a rozšiřující knihovny MFC DLL, které načte.

Kvůli problémům s manglingem a exportem názvů jazyka C++ se seznam exportu z knihovny DLL rozšíření MFC může lišit mezi ladicí a maloobchodní verzí stejné knihovny DLL a knihoven DLL pro různé platformy. Maloobchodní MFCx0.dll má asi 2 000 exportovaných vstupních bodů; Ladicí MFCx0D.dll má asi 3 000 exportovaných vstupních bodů.

Správa paměti

Knihovny DLL MFCx0.dll a všechny rozšiřující knihovny MFC načtené do adresního prostoru klientské aplikace používají stejný alokátor paměti, načítání prostředků a další globální stavy MFC, jako by byly ve stejné aplikaci. To je důležité, protože knihovny KNIHOVNY DLL jiné než MFC a běžné knihovny MFC DLL provádějí přesně opačně a mají všechny knihovny DLL přidělené z vlastního fondu paměti.

Pokud knihovna DLL rozšíření MFC přiděluje paměť, může tato paměť volně intermixovat s jakýmkoli jiným objektem přiděleným aplikací. Navíc, pokud aplikace, která dynamicky odkazuje na MFC, selže, ochrana operačního systému udržuje integritu všech ostatních aplikací MFC sdílejících knihovnu DLL.

Podobně jsou mezi klientskou aplikací a všemi rozšiřujícími knihovnami DLL knihovny MFC sdíleny také další globální stavy MFC, jako je aktuální spustitelný soubor pro načtení prostředků, a také samotná knihovna DLL MFCx0.dll.

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

Export prostředků se provádí prostřednictvím seznamu prostředků. Každá aplikace obsahuje ingly propojený seznam objektů CDynLinkLibrary . Při hledání prostředku se většina standardních implementací MFC, které načítají prostředky, nejprve podívá na aktuální modul prostředků (AfxGetResourceHandle) a pokud se prostředek nenajde, projděte si seznam objektů CDynLinkLibrary , které se pokoušejí načíst požadovaný prostředek.

Procházení seznamu má nevýhody, že je mírně pomalejší a vyžaduje správu rozsahů ID prostředků. Má výhodu, že klientská aplikace, která odkazuje na několik rozšiřujících knihoven DLL, může použít libovolný prostředek poskytovaný knihovnou DLL, aniž by bylo nutné zadat popisovač instance knihovny DLL. AfxFindResourceHandle je rozhraní API sloužící k procházení seznamu prostředků k vyhledání dané shody. Vezme název a typ prostředku a vrátí popisovač prostředku, kde byl poprvé nalezen (nebo NULL).

Pokud nechcete procházet seznam a načítat pouze prostředky z určitého místa, použijte funkce AfxGetResourceHandle a AfxSetResourceHandle uložte starý popisovač a nastavte nový popisovač. Než se vrátíte do klientské aplikace, nezapomeňte starý popisovač prostředku obnovit. Příklad použití tohoto přístupu k explicitní načtení nabídky naleznete v souboru Testdll2 .cpp v ukázkové knihovně DLLHUSK knihovny MFC.

Dynamické vytváření objektů MFC s názvem MFC je podobné. Mechanismus deserializace objektu MFC musí mít zaregistrované všechny CRuntimeClass objekty, aby bylo možné rekonstruovat dynamickým vytvořením objektů jazyka C++ požadovaného typu na základě toho, co bylo uloženo dříve.

V případě ukázkové knihovny DLLHUSK mfc vypadá seznam přibližně takto:

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 verzi 4.2.

Knihovna MFCxx.dll je obvykle poslední v seznamu prostředků a tříd. MFCxx.dll obsahuje všechny standardní prostředky MFC, včetně řetězců výzvy pro všechny standardní ID příkazů. Umístění na konec seznamu umožňuje knihovny DLL a samotná klientská aplikace nemají vlastní kopii standardních prostředků MFC, ale spoléhat se na sdílené prostředky v MFCxx.dll.

Sloučení prostředkůach prostředků a názvů všech knihoven DLL do prostoru názvů klientské aplikace má nevýhodu, že budete muset být opatrní s tím, jaké ID nebo názvy vyberete.

Ukázka KNIHOVNY DLLHUSK spravuje sdílený prostor názvů prostředků pomocí více souborů hlaviček.

Pokud vaše knihovna DLL rozšíření MFC potřebuje udržovat extra data pro každou aplikaci, můžete odvodit novou třídu z CDynLinkLibrary a vytvořit ji v DllMain. Při spuštění může knihovna DLL zkontrolovat seznam aktuální aplikace CDynLinkLibrary objekty a najít ten pro konkrétní knihovnu DLL rozšíření MFC.

Co chcete udělat?

O čem chcete vědět víc?

Viz také

Vytváření knihoven DLL jazyka C/C++ v sadě Visual Studio