Sdílet prostřednictvím


TN033: Verze knihovny DLL MFC

Tato poznámka popisuje, jak lze použít MFCxx.DLL a MFCxxD.DLL (kde x je číslo verze MFC) s MFC aplikace a knihovny DLL rozšíření sdílené knihovny DLL.Další informace o pravidelných knihovny DLL, viz Pomocí MFC jako součást knihovny DLL.

Tato technická Poznámka zahrnuje tři aspekty knihoven DLL.Poslední dva jsou pro pokročilé uživatele:

  • Jak vytvářet MFC rozšiřující knihovna DLL

  • Jak vytvářet aplikace MFC používá verzi knihovny DLL MFC

  • Jak MFC sdílené knihovny DLL jsou implementovány.

Pokud se zajímáte o vytváření knihovny DLL pomocí MFC, který lze použít s aplikací bez MFC (to se nazývá pravidelné DLL), Technická poznámka 11.

Přehled podpory MFCxx.DLL: terminologie a soubory

Knihovna DLL pravidelně: vytváření samostatných DLL používání některých tříd MFC pomocí pravidelných knihovny DLL.Přes hranice aplikace nebo knihovna DLL rozhraní jsou rozhraní "C" a klientské aplikace nemusí být aplikace MFC.

Toto je verze knihovny DLL podpory podporovány MFC 1.0.Je popsán v Technická poznámka 11 a pokročilé koncepty MFC vzorku DLLScreenCap.

[!POZNÁMKA]

Od Visual C++ verze 4.0 termín knihovna USRDLL je zastaralý a nahrazuje pravidelné DLL, který staticky odkazuje na MFC.Může také vytvořit pravidelné knihovny DLL, která propojí dynamicky MFC.

MFC 3.0 (a vyšší) podporuje pravidelné knihovny DLL s novými funkcemi včetně třídy OLE a databáze.

AFXDLL: Toto je také nazýváno sdílenou verzi knihovny MFC.Toto je nová podpora knihovny DLL v MFC 2.0.Samotné knihovny MFC je počet knihoven DLL (popsáno níže) a klientské aplikace nebo knihovna DLL knihovny DLL, které vyžaduje propojení dynamicky.Rozhraní přes hranice aplikace nebo knihovna DLL jsou C + +/ rozhraní třídy MFC.Aplikace MFC musí být klientská aplikace.To podporuje všechny funkce MFC 3.0 (výjimka: UNICODE nejsou podporovány databáze tříd).

[!POZNÁMKA]

Visual C++ verze 4.0 od tohoto typu DLL je označován jako "Příponu DLL."

Tato poznámka bude používat MFCxx.DLL odkazuje na celou MFC knihovnu DLL sady, která zahrnuje:

  • Ladění: MFCxxD.DLL (kombinace) a MFCSxxD.LIB (statické).

  • Verze: MFCxx.DLL (kombinace) a MFCSxx.LIB (statické).

  • Program Unicode Debug: MFCxxUD.DLL (kombinace) a MFCSxxD.LIB (statické).

  • Verze Unicode: MFCxxU.DLL (kombinace) a MFCSxxU.LIB (statické).

[!POZNÁMKA]

MFCSxx [U] [D].LIB knihovny se používají ve spojení s jednotka MFC sdílené knihovny DLL.Tyto knihovny obsahují kód, který musí být staticky propojeny aplikace nebo knihovna DLL.

Aplikací obsahuje odkazy na odpovídající import knihovny:

  • Ladění: MFCxxD.LIB

  • Verze: MFCxx.LIB

  • Unicode ladění: MFCxxUD.LIB

  • Verze Unicode: MFCxxU.LIB

"Příponu DLL MFC" je postavena MFCxx.DLL knihovny DLL (nebo jiné MFC sdílené knihovny DLL).Zde komponentové architektury MFC dojde.Pokud užitečné třída odvozena ze třídy MFC nebo vytvořit jiné podobné MFC toolkit, můžete je umístit do knihovny DLL.Že DLL používá MFCxx.DLL, stejně jako ultimate klientské aplikace.To umožňuje opakovaně listu třídy, opakovaně základní třídy a třídy opakovaně zobrazit nebo dokument.

Výhody a nevýhody

Proč používat sdílenou verzi MFC?

  • Použití sdílené knihovny, může mít za následek menší aplikací (minimální aplikace, která používá většina knihovna MFC je méně než 10 kB).

  • Sdílenou verzi MFC podporuje knihovny DLL rozšíření standardu MFC a pravidelné knihovny DLL.

  • Vytvoření aplikace, která používá sdílené knihovny MFC je rychlejší než budování staticky propojené aplikace MFC protože není nezbytné propojit MFC sám.To platí zejména v ladění sestavení, kde musí vytvořeném propojovacím kompaktní ladicích informací – propojením s knihovny DLL obsahující informace o ladění je méně ladicích informací do kompaktního v rámci aplikace.

Proč nelze používat sdílenou verzi MFC:

  • Aplikace, která používá sdílené knihovny dopravy vyžaduje lodí MFCxx.DLL (a jiné) knihovny s programem.MFCxx.DLL je volně redistributable stejně jako mnoho knihoven DLL, ale je stále nutné nainstalovat DLL instalačního programu.Kromě toho musí dodat MSVCRTxx.DLL, obsahující c runtime knihovny, který používá program a samotné knihovny DLL MFC.

Jak psát knihovna DLL rozšíření MFC

MFC rozšiřující knihovna DLL je knihovna DLL obsahující třídy a funkce, které jsou zapsány na tomto funkce tříd MFC.MFC rozšiřující knihovna DLL sdílené knihovny DLL MFC používá stejným způsobem, jakým aplikace používá, s několika další požadavky:

  • Procesu vytváření podobná vytváření aplikace, která používá sdílené knihovny MFC několik dalších kompilátor a linker možnosti.

  • MFC rozšiřující knihovna DLL nemá CWinApp-odvozené třídy.

  • MFC rozšiřující knihovna DLL musí poskytnout zvláštní DllMain.Dodává AppWizard DllMain funkce, které lze změnit.

  • Rutina pro inicializaci vytvoření obvykle poskytne MFC rozšiřující knihovna DLL CDynLinkLibrary Pokud příponu DLL přeje vyvážet CRuntimeClasses nebo Používání zdrojů.Odvozené třídy CDynLinkLibrary je možné použít dat aplikace musí být zachována příponu DLL.

Tyto úvahy jsou podrobněji popsány v níže.Rovněž vztahovat na vzorku MFC pokročilé koncepty DLLHUSK od ilustruje:

  • Vytváření aplikace pomocí sdílených knihoven.(DLLHUSK.EXE je dynamicky odkazy na knihovny MFC i další knihovny DLL aplikace MFC).

  • Vytváření knihovny DLL rozšíření MFC.(Zvláštní příznaky poznámek jako _AFXEXT , jsou při vytváření knihovny DLL rozšíření)

  • Dva příklady knihovny DLL rozšíření standardu MFC.Jeden ukazuje základní strukturu příponu DLL MFC, omezené vývozy (TESTDLL1) a další pořady Export celé třídy rozhraní (TESTDLL2).

Klientské aplikace a všechny knihovny DLL rozšíření musí používat stejnou verzi MFCxx.DLL.By podle úmluvy MFC DLL a poskytovat i ladění a maloobchod (/ release) verze knihovna DLL rozšíření.To umožňuje klientským programům sestavení ladicí i prodejní verze svých aplikací a jejich propojení s příslušnou ladění nebo prodejní verzi všech knihoven DLL.

[!POZNÁMKA]

Protože C++ název pozměnění a exportovat problémy, může být exportovat seznam z rozšíření knihovny DLL pro různé platformy liší ladění a maloobchodní verze stejné knihovně DLL a knihovny DLL.Maloobchodní MFCxx.DLL asi 2000 vyvážel vstupní body; ladění MFCxxD.DLL vyvážel přibližně 3000 vstupních bodů.

hw85e4bb.collapse_all(cs-cz,VS.110).gifRychlé poznámky na Správa paměti

V části "Správa paměti," téměř na konci této technické poznámky popisuje provádění MFCxx.DLL s sdílenou verzi MFC.Informace, které potřebujete implementovat pouze knihovny DLL rozšíření je zde popsáno.

MFCxx.DLL a všechny přípony DLL načten klientskou aplikaci adresní prostor budou používat stejné přidělování paměti, načítání prostředku a ostatní státy "globální" MFC jako kdyby byly ve stejné aplikaci.To je důležité, protože knihovny MFC DLL a pravidelné knihovny DLL, které staticky odkazují na MFC to přesný opak a mít každý DLL přidělení z vlastního fondu paměti.

Pokud knihovna DLL rozšíření přidělí paměť, pak že paměť můžete libovolně kombinovat u jakéhokoli jiného objektu aplikace přiděleny.Také pokud dojde k chybě aplikace, která používá sdílené knihovny MFC, ochranu operačního systému zachovávat integritu jiných MFC aplikace sdílení DLL.

Podobně také jiných států "globální" MFC, stejně jako aktuální spustitelný soubor načíst prostředky, sdíleny mezi klientskou aplikací a všechny knihovny DLL rozšíření standardu MFC, stejně jako MFCxx.DLL sám.

hw85e4bb.collapse_all(cs-cz,VS.110).gifVytváření knihovny DLL rozšíření

AppWizard můžete použít k vytvoření projektu MFC příponu DLL a bude automaticky generovat linker nastavení a odpovídající kompilátoru.Byla také generovat DllMain funkce, které lze změnit.

Převodem existujícího projektu knihovna DLL rozšíření MFC začínají standardní pravidla pro vytváření aplikace pomocí sdílenou verzi MFC a potom proveďte následující:

  • Přidat /D_AFXEXT k příznakům kompilátoru.V dialogovém okně Vlastnosti projektu vyberte uzel C/C++.Vyberte kategorii preprocesoru.Přidat _AFXEXT pole definovat makra oddělující jednotlivé položky středníkem.

  • Odebrat /Gy přepínač kompilátoru.V dialogovém okně Vlastnosti projektu vyberte uzel C/C++.Vyberte kategorii generování kódu.Zajistit, že není povolena možnost "Povolit funkci úroveň propojení".To usnadní protože vytvořeném propojovacím neodebere na které neexistuje odkaz funkce Export tříd.Pokud původní projekt je použit k vytvoření pravidelných DLL staticky propojeny MFC změnit /MT [d možnost kompilátoru přepínače [d.

  • Sestavení knihovny exportu /DLL možnost propojení.Tato možnost nastaví při vytváření nového cíle jako typ cílového určení knihovny DLL Win32.

hw85e4bb.collapse_all(cs-cz,VS.110).gifZměna záhlaví souborů

Cílem rozšíření knihovny DLL je obvykle některé běžné funkce Exportovat do jedné nebo více aplikací využívající tuto funkci.Tato boils export tříd a globální funkce, které jsou k dispozici pro klientské aplikace.

K tomu musí zajistit, že každá funkce členů je označena jako importovat nebo exportovat jako vhodné.To vyžaduje zvláštní prohlášení: __declspec(dllexport) a __declspec(dllimport).Při použití třídy v klientských aplikacích je deklarován jako chcete __declspec(dllimport).Při vytváření rozšiřující knihovny DLL, samotný by měl být deklarován jako __declspec(dllexport).Navíc funkce musí být skutečně vyvezeno, aby klientské programy vázat na ně při zatížení.

Chcete-li exportovat celou třídu pomocí AFX_EXT_CLASS v definici třídy.Toto makro je definována jako rozhraní __declspec(dllexport) při _AFXDLL a _AFXEXT je definována, ale definován jako __declspec(dllimport) při _AFXEXT není definována._AFXEXTjak je popsáno výše, je definována pouze v při vytváření knihovna DLL rozšíření.Příklad:

class AFX_EXT_CLASS CExampleExport : public CObject
{ ... class definition ... };

hw85e4bb.collapse_all(cs-cz,VS.110).gifNeexportování celé třídy

Někdy můžete chtít exportovat pouze jednotlivé nezbytné členy vaší třídy.Například pokud exportujete třídu odvozenou od CDialog, můžete potřebovat exportovat pouze konstruktor a volání DoModal.Exportovat tyto členy pomocí na knihovnu DLL.Soubor DEF, ale můžete také použít AFX_EXT_CLASS mnohem způsobem na jednotlivé členy potřebujete exportovat.

Příklad:

class CExampleDialog : public CDialog
{
public:
   AFX_EXT_CLASS CExampleDialog();
   AFX_EXT_CLASS int DoModal();
   // rest of class definition
   .
   .
   .
};

Pokud to uděláte, můžete spustit do další problém protože exportujete již všechny členy třídy.Problém je ve způsobu práce MFC makra.Několik podpůrných maker knihovny MFC ve skutečnosti deklaruje nebo definuje datové členy.Proto tyto datové členy také muset vyvážené z knihovny DLL.

Například makro DECLARE_DYNAMIC je definováno takto při vytváření rozšiřující knihovny DLL:

#define DECLARE_DYNAMIC(class_name) \
protected: \
   static CRuntimeClass* PASCAL _GetBaseClass(); \
   public: \
   static AFX_DATA CRuntimeClass class##class_name; \
   virtual CRuntimeClass* GetRuntimeClass() const; \

Řádek, který začíná "statické AFX_DATA" prohlašuje statický objekt uvnitř vaší třídy.Tato třída správně exportovat a přístup k informacím runtime z klienta.EXE, je třeba exportovat tento statický objekt.Protože je statický objekt deklarován s modifikátorem AFX_DATA, potřebujete pouze definovat AFX_DATA na __declspec(dllexport), při sestavování vaší knihovny DLL, a definovat jej jako __declspec(dllimport), při sestavování vašeho klientského spustitelného souboru.

Jak je popsáno výše, AFX_EXT_CLASS je již definována tímto způsobem.Stačí re-define AFX_DATA stejná jako AFX_EXT_CLASS kolem své definice třídy.

Příklad:

   #undef  AFX_DATA
   #define AFX_DATA AFX_EXT_CLASS
   class CExampleView : public CView
   {
     DECLARE_DYNAMIC()
     // ... class definition ...
   };
   #undef  AFX_DATA
   #define AFX_DATA

MFC používá vždy AFX_DATA symbol na datové položky se definuje v rámci jeho makra tak, aby tento postup bude fungovat u všech scénářů.Například bude pracovat pro DECLARE_MESSAGE_MAP.

[!POZNÁMKA]

Chcete-li exportovat celou třídu, nikoli pouze vybrané členy dané třídy, jsou statické datové členy automaticky exportovány.

Stejný postup můžete automaticky exportovat CArchive extrakce operátor pro třídy pomocí DECLARE_SERIAL a IMPLEMENT_SERIAL makra.Exportovat operátor archivu bracketing deklarace tříd (v.Soubor H) s následujícím kódem:

#undef AFX_API
#define AFX_API AFX_EXT_CLASS

<your class declarations here>

#undef AFX_API
#define AFX_API

hw85e4bb.collapse_all(cs-cz,VS.110).gifOmezení _AFXEXT

Můžete použít _AFXEXT pre-processor symbol pro vaše příponu DLL, pokud nemáte více vrstev knihovny DLL rozšíření.Máte-li rozšiřující knihovny DLL, které volají nebo jsou odvozeny od tříd ve vaší vlastní rozšiřující knihovně DLL, která je potom odvozena od tříd knihovny MFC, je nutné se vyhnout dvojznačnosti použitím vašeho vlastního symbolu preprocesoru.

Problém je, že ve Win32 musíte explicitně deklarovat všechna data jako __declspec(dllexport) pokud mají být exportovány z knihovny DLL a __declspec(dllimport) pokud mají být importovány z knihovny DLL.Když nadefinujete _AFXEXT, hlavičky knihovny MFC se ujistí, že je správně definován AFX_EXT_CLASS.

Když máte více vrstev, jeden symbol jako AFX_EXT_CLASS nestačí, protože knihovna DLL rozšíření mohou být export nových tříd stejně jako ostatní třídy import z jiného rozšiřující knihovny DLL.K řešení tohoto problému použijte speciální preprocesoru symbol, který označuje vytváříte DLL sám versus pomocí knihovny DLL.Představte si například dva příponu DLL, A.DLL a B.DLL.Každý exportovat některé třídy A.H a B.H.B.dll používá třídy z A.DLL.Soubory hlaviček by vypadaly přibližně takto:

/* A.H */
#ifdef A_IMPL
   #define CLASS_DECL_A   __declspec(dllexport)
#else
   #define CLASS_DECL_A   __declspec(dllimport)
#endif

class CLASS_DECL_A CExampleA : public CObject
{ ... class definition ... };

/* B.H */
#ifdef B_IMPL
   #define CLASS_DECL_B   __declspec(dllexport)
#else
   #define CLASS_DECL_B   __declspec(dllimport)
#endif

class CLASS_DECL_B CExampleB : public CExampleA
{ ... class definition .. };

Integrovaný A.DLL je integrována s /D A_IMPL a B.DLL je vytvořena, je integrována s /D B_IMPL.Pomocí samostatného symbolů pro každý soubor DLL CExampleB exportu a importu při vytváření B.DLL CExampleA.CExampleA při exportu při vytváření A.DLL a importován při B.DLL (nebo jiného klienta).

Tento typ rozvrstvení nelze provést při použití integrovaná AFX_EXT_CLASS a _AFXEXT symboly preprocesoru.Výše popsaná technika řeší tento problém není na rozdíl od způsobem mechanismus MFC sama používá při vytváření jeho OLE, databáze a sítě příponu DLL.

hw85e4bb.collapse_all(cs-cz,VS.110).gifNeexportování celé třídy

Znovu budete muset věnovat zvláštní pozornost, když exportujete není celou třídu.Je třeba zajistit nezbytné datové položky vytvořené pomocí maker MFC jsou exportována správně.To lze provést re-defining AFX_DATA makro do konkrétní třídy.Toto by mělo být provedeno kdykoli, když neexportujete celou třídu.

Příklad:

// A.H
#ifdef A_IMPL
   #define CLASS_DECL_A  _declspec(dllexport)
#else
   #define CLASS_DECL_A  _declspec(dllimport)
   #endif

#undef  AFX_DATA
#define AFX_DATA CLASS_DECL_A

class CExampleA : public CObject
{
   DECLARE_DYNAMIC()
   CLASS_DECL_A int SomeFunction();
   //class definition 
   .
   .
   .
};

#undef AFX_DATA
#define AFX_DATA

hw85e4bb.collapse_all(cs-cz,VS.110).gifDllMain

Následuje přesný kód, měli byste umístit do hlavní zdrojový soubor knihovna DLL rozšíření.By měly pocházet, po zahrnuje standardní.Všimněte si, že při použití AppWizard k vytvoření souborů DLL rozšíření starter dodává DllMain pro vás.

#include "afxdllx.h"

static AFX_EXTENSION_MODULE extensionDLL;

extern "C" int APIENTRY 
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
{
   if (dwReason == DLL_PROCESS_ATTACH)
   {
      // Extension DLL one-time initialization 
      if (!AfxInitExtensionModule(
             extensionDLL, hInstance))
         return 0;

      // TODO: perform other initialization tasks here
   }
   else if (dwReason == DLL_PROCESS_DETACH)
   {
      // Extension DLL per-process termination
      AfxTermExtensionModule(extensionDLL);

          // TODO: perform other cleanup tasks here
   }
   return 1;   // ok
}

Volání AfxInitExtensionModule zachycuje modulů runtime třídy (CRuntimeClass struktur) stejně jako jeho továrny objektu (COleObjectFactory objekty) pro použití při vyšší CDynLinkLibrary je vytvořen objekt.Volání (volitelné) AfxTermExtensionModule umožňuje MFC vyčištění rozšiřující knihovny DLL při odpojí každého procesu (který se stane při ukončení procesu nebo knihovny DLL je vyloženo v důsledku FreeLibrary volání) z rozšiřující knihovny DLL.Protože většina příponu DLL není načten dynamicky (obvykle jsou propojeny prostřednictvím jejich import knihovny), volání AfxTermExtensionModule obvykle není nutné.

Načtení a uvolnění dynamické knihovny DLL rozšíření aplikace nezapomeňte volání AfxTermExtensionModule uvedené výše.Je také nutné používat AfxLoadLibrary a AfxFreeLibrary (namísto funkce Win32 LoadLibrary a FreeLibrary) Pokud aplikace používá více podprocesů, nebo pokud to dynamicky načítá knihovna DLL rozšíření.Pomocí AfxLoadLibrary a AfxFreeLibrary pojistitelům spouštěcí a ukončovací kód, když je načítání a uvolňování knihoven DLL rozšíření není poškozený globální stav MFC.

Záhlaví souboru AFXDLLX.Zvláštní definice použité v DLL rozšíření, jako je například definice struktury obsahuje h AFX_EXTENSION_MODULE a CDynLinkLibrary.

Globální extensionDLL musí být deklarovány jako zobrazeny.Na rozdíl od 16bitové verze MFC, přidělení paměti a volat funkce MFC během této doby, protože MFCxx.DLL plně inicializován v době vaší DllMain se nazývá.

hw85e4bb.collapse_all(cs-cz,VS.110).gifSdílení prostředků a tříd

Jednoduché knihovny DLL rozšíření standardu MFC je třeba exportovat pouze několik funkcí nízkorychlostní klientské aplikace a nic víc.Další intenzivní knihovny DLL uživatelského rozhraní chtít exportovat klientské aplikace zdroje a C++ tříd.

Export prostředků je realizován prostřednictvím seznamu prostředků.V každé žádosti je jednotlivě propojený seznam CDynLinkLibrary objektů.Při hledání zdroje většinu standardních implementace MFC, které zatížení prostředků vypadat nejprve aktuálního modulu prostředku (AfxGetResourceHandle) a pokud nebyla nalezena chůze seznam CDynLinkLibrary objekty při pokusu o načtení požadovaného prostředku.

Dynamické vytváření objektů C++ uveden název třídy C++ je podobné.Mechanismus pro rekonstrukci objektu MFC musí mít všechny CRuntimeClass registrované objekty tak, že lze rekonstrukce dynamicky vytvořením C++ objekt typu požadované na základě co byla dříve uložena.

Pokud chcete, aby klientské aplikace používají třídy knihovna DLL rozšíření, které jsou DECLARE_SERIAL, je třeba exportovat své třídy viditelný klientské aplikace.To je také provést chodí CDynLinkLibrary seznam.

V případě vzorku MFC pokročilé koncepty DLLHUSK, seznam vypadá asi takto:

head ->   DLLHUSK.EXE   - or -   DLLHUSK.EXE
               |                      |
          TESTDLL2.DLL           TESTDLL2.DLL
               |                      |
          TESTDLL1.DLL           TESTDLL1.DLL
               |                      |
               |                      |
            MFC90D.DLL            MFC90.DLL

MFCxx.DLL je obvykle poslední v seznamu zdrojů a třídy.MFCxx.DLL zahrnuje všechny standardní MFC prostředky včetně řetězce výzvy pro všechna ID standardního příkazu.Umístění na konci seznamu umožňuje knihoven DLL a aplikaci klienta nebude mít své vlastní kopii standardní prostředky MFC, ale se spoléhají na sdílené prostředky v MFCxx.DLL místo.

Sloučení zdrojů a názvů třídy všech knihoven DLL do oboru názvů aplikace klient má nevýhodou, kterou je třeba pečlivě co ID nebo názvy vybraných.Můžete samozřejmě zakázat tuto funkci není buď Export zdroje nebo CDynLinkLibrary objektu do klientské aplikace.Příklad DLLHUSK pravuje jménný prostor sdílených prostředků použitím více hlavičkových souborů.Viz Technická poznámka 35 další tipy pro používání souborů sdílených prostředků.

hw85e4bb.collapse_all(cs-cz,VS.110).gifInicializace knihovny DLL

Jak bylo uvedeno výše, obvykle můžete vytvořit CDynLinkLibrary objektu, který chcete exportovat do aplikace klienta prostředky a třídy.Musíte poskytnout exportovaný vstupní bod knihovny DLL inicializace.Minimální je void rutina, která nevyžaduje žádné argumenty a vrátí nic, ale může být cokoliv, co potřebujete.

Každá klientská aplikace, která chce používat knihovny DLL musí volat toto Inicializační rutina Pokud použijete tento přístup.Může to také přidělit CDynLinkLibrary objektu v vaše DllMain pouze po volání AfxInitExtensionModule.

Inicializační rutina musíte vytvořit CDynLinkLibrary objektu v aktuální aplikaci haldy, zapojený do vaší příponu DLL informace.To lze provést takto:

extern "C" extern void WINAPI InitXxxDLL()
{
   new CDynLinkLibrary(extensionDLL);
}

Rutinní název InitXxxDLL v tomto příkladu může být cokoliv chcete.Nemusí být extern "C", ale tím to umožňuje snazší správa exportovat seznam.

[!POZNÁMKA]

Pokud vaše rozšiřující knihovny DLL od pravidelných DLL je nutné exportovat tuto funkci inicializace.Tato funkce musí být volána z pravidelných DLL před použitím všech tříd příponu DLL nebo zdroje.

hw85e4bb.collapse_all(cs-cz,VS.110).gifExport položky

Jednoduchý způsob exportu vašich tříd je použití __declspec(dllimport) a __declspec(dllexport) na každé třídy a globální funkce, které chcete exportovat.Je mnohem snazší, ale je méně efektivní než od méně kontrolu nad funkce exportu a řadové exportovat funkce pojmenování každé vstupní bod (viz dále).TESTDLL1 a TESTDLL2 pomocí této metody jejich položky exportovat.

Efektivnější způsob (a metody používané v MFCxx.DLL) je exportovat jednotlivé položky ručně podle názvů jednotlivých položek v.Soubor HD.Protože jsme exportovat výběrové vývozy z naší DLL (to znamená, že není vše), jsme musí rozhodnout určitého rozhraní, která jsme chcete exportovat.To je obtížné, protože je nutné zadat pozměnění názvů na vytvořeném propojovacím ve formuláři položky v.Soubor HD.Exportovat všechny třídy C++ Pokud skutečně potřebujete pro ni mít symbolický odkaz.

Pokud jste vyzkoušeli export C++ tříd s.DEF souboru před chcete vyvinout nástroj automaticky generovat tohoto seznamu.To lze provést pomocí odkazu dvoustupňový proces.Propojení knihovny DLL jednou s vývozy a umožňuje linker generovat.Soubor MAPY.Na.Soubor MAPY lze vygenerovat seznam funkcí, které by měly být exportovány, tak s některé nové uspořádání jej lze generovat EXPORT položek vašeho.Soubor HD.Exportovat seznam MFCxx.DLL a OLE a knihovny DLL rozšíření databáze, několik tisíc číslo vygenerované takového procesu (i když není zcela automatická a vyžaduje některé straně optimalizace vždy jednou za chvíli).

hw85e4bb.collapse_all(cs-cz,VS.110).gifCWinApp vs.CDynLinkLibrary

MFC rozšiřující knihovna DLL nemá CWinApp-odvozené objekt jeho vlastní; místo toho musí pracovat CWinApp-odvozené objekt klientské aplikace.To znamená, klientské aplikace a podobně vlastní čerpadlo hlavní zpráva nečinnosti smyčky.

Knihovny DLL rozšíření MFC potřebuje-li zachovat data navíc pro každou aplikaci, můžete odvodit nové třídy z CDynLinkLibrary a vytvořit v InitXxxDLL rutina popisu výše.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.

hw85e4bb.collapse_all(cs-cz,VS.110).gifPoužití prostředků v implementaci knihovny DLL

Jak bylo uvedeno výše, bude zatížení prostředků výchozí vás seznam CDynLinkLibrary objekty, které hledají první EXE nebo DLL, která obsahuje požadovaný prostředek.Všechna rozhraní API MFC, jakož i všechny vnitřní kód používá AfxFindResourceHandle pro vás seznam zdrojů k vyhledání všech prostředků, bez ohledu na to, kde mohou být umístěny.

Pokud chcete načíst pouze prostředky z určitého místa, pomocí rozhraní API AfxGetResourceHandle a AfxSetResourceHandle uložit původní úchyt a nastavit nový úchyt.Nezapomeňte obnovit starý popisovač prostředku před jeho vrácením do klientské aplikace.Vzorek TESTDLL2 používá tento přístup výslovně načítání nabídky.

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).

Zapisování aplikace, která používá verzi knihovny DLL

hw85e4bb.collapse_all(cs-cz,VS.110).gifPožadavky aplikace

Aplikace, která používá sdílenou verzi MFC je třeba provést několik jednoduchých pravidel:

  • Musí mít CWinApp objektu a postupujte podle standardních pravidel pro zprávy čerpadla.

  • Musí být kompilována s sadu příznaků požadované kompilátoru (viz níže).

  • Je nutné propojit s import knihovny MFCxx.Nastavení kompilátoru požadované příznaky záhlaví MFC určit v okamžiku propojení knihovny, které aplikace by měla propojit s.

  • Chcete-li spustit spustitelný soubor musí být MFCxx.DLL na cestě nebo v adresáři systému Windows.

hw85e4bb.collapse_all(cs-cz,VS.110).gifBudovy s vývojové prostředí

Používáte interní makefile s většinou standardní výchozí hodnoty, můžete snadno změnit projekt vytvoření verze knihovny DLL.

Následující krok předpokládá, že máte správně fungující MFC aplikace propojené s NAFXCWD.LIB (pro ladění) a NAFXCW.LIB (pro maloobchodní) a chcete ji použít sdílenou verzi knihovny MFC.Používáte prostředí Visual C++ a soubor interní projekt.

  1. Na projekty nabídky, klepněte na tlačítko Vlastnosti.V Obecné stránky pod Výchozí projekt, Microsoft Foundation Classes nastavena na MFC pro použití v knihovně DLL sdílené (MFCxx(d).dll).

hw85e4bb.collapse_all(cs-cz,VS.110).gifBudovy s NMAKE

Pokud jsou funkce externího souboru makefile Visual C++ nebo přímo pomocí NMAKE, bude nutné upravit makefile a kompilátor a linker možnosti podpory

Kompilátor požadované příznaky:

  • / PŘEPÍNAČE D_AFXDLL
    / D_AFXDLL

Standardní záhlaví MFC je nutné definovat tento symbol:

  • PŘEPÍNAČE
    Aplikace musí používat verzi C Runtime knihovny DLL

Všechny ostatní příznaky kompilátor podle výchozí MFC (například _DEBUG pro ladění).

Upravte seznam linker knihoven.Změna NAFXCWD.LIB k MFCxxD.LIB a NAFXCW změnit.LIB k MFCxx.LIB.Nahraďte LIBC.LIB s MSVCRT.LIB.S jinými knihovna MFC je důležité, že je umístěn MFCxxD.LIB před všechny c runtime knihovny.

Volitelně přidat /D_AFXDLL na volby kompilátoru prodejní a ladicí prostředek (která skutečně zkompiluje zdrojů s /R).Díky své konečné spustitelný soubor menší sdílení prostředků, které jsou k dispozici v knihovnách DLL MFC.

Po provedení těchto změn je nutné plně sestavení.

hw85e4bb.collapse_all(cs-cz,VS.110).gifVytváření vzorků

Většina programů MFC vzorku je možné sestavit z Visual C++ nebo sdílené MAKEFILE kompatibilní NMAKE z příkazového řádku.

Chcete-li převést všechny tyto vzorky použít MFCxx.DLL, můžete načíst.MAK souborů do jazyka Visual C++ a nastavit možnosti projektu, jak je popsáno výše.Pokud používáte sestavení NMAKE, můžete zadat "AFXDLL = 1 na NMAKE příkazový řádek a který bude stavět vzorku pomocí sdílených knihoven MFC.

Pokročilé koncepty MFC vzorku DLLHUSK je integrována s verzí knihovny DLL MFC.Tento vzorek nejen ukazuje, jak vytvořit aplikaci, která je spojena s MFCxx.DLL, ale ilustruje možnost balení MFC DLL jako knihovny DLL rozšíření standardu MFC popsané dále v této technické poznámce Další funkce.

hw85e4bb.collapse_all(cs-cz,VS.110).gifPoznámky k balení

Prodejní verze knihoven DLL (MFCxx [U].(DLL) jsou volně redistributable.Ladicí verze knihoven DLL nejsou volně redistributable a měli použít pouze během vývoje aplikace.

Ladění knihoven DLL jsou poskytnuty informace o ladění.Spuštění aplikace, stejně jako knihovny DLL lze sledovat pomocí ladicího programu jazyka Visual C++.Verze knihovny DLL (MFCxx [U].(DLL) neobsahují informace o ladění.

Přizpůsobit nebo sestavení knihovny DLL, pak by volání je něco než "MFCxx" MFC SRC soubor MFCDLL.MAK popisuje možnosti sestavení a obsahuje logiku pro přejmenování souborů DLL.Přejmenování souborů je nezbytné, protože mnoho aplikací MFC možná sdílena těchto knihoven DLL.S vlastní verze knihoven DLL MFC nahradit nainstalovaná v systému přerušit jinou aplikaci MFC pomocí sdílené knihovny DLL MFC.

Opětovné sestavení knihovny DLL MFC není doporučeno.

Způsob implementace MFCxx.DLL

Následující část popisuje způsob implementace MFC knihovnu DLL (MFCxx.DLL a MFCxxD.DLL).Principy podrobnosti zde nejsou také důležité všechny Chcete-li provést je pomocí aplikace MFC knihovnu DLL.Nejsou zde podrobnosti nezbytné pro pochopení jak psát knihovna DLL rozšíření MFC, ale Principy této implementace můžete zapsat vlastní knihovny DLL.

hw85e4bb.collapse_all(cs-cz,VS.110).gifPřehled provádění

MFC DLL je skutečně zvláštní případ MFC rozšiřující knihovna DLL výše popsaným způsobem.Má velký počet vývozy pro velký počet tříd.Existuje několik dalších možností udělat v knihovně DLL MFC provést zvláštní ještě více než běžné rozšiřující knihovna DLL.

hw85e4bb.collapse_all(cs-cz,VS.110).gifWin32 nepodporuje většinu práce

16Bitové verze MFC potřebný počet zvláštních postupů, včetně dat aplikace na segmentu zásobníku speciální segmenty vytvořeny některé kódu sestavení 80 x 86, výjimka proces kontextů a jiných technik.Win32 přímo podporuje-zpracování dat v knihovně DLL, která je co má většinu času.Většinou je MFCxx.DLL pouze NAFXCW.LIB zabalen v knihovně DLL.Pokud se podíváte na zdrojový kód MFC, zjistíte velmi málo #ifdef _AFXDLL, protože je velmi málo zvláštních případech, které je třeba provést.Zvláštní případy, které jsou konkrétně řešit Win32 v systému Windows 3.1 (jinak nazývána Win32s).Win32s nemá podpora-proces DLL data přímo tak MFC knihovnu DLL, musíte použít podproces místní úložiště (TLS) získat data místní proces rozhraní Win32 API.

hw85e4bb.collapse_all(cs-cz,VS.110).gifDopad na další soubory knihovny zdrojů

Dopad _AFXDLL verze v běžných zdrojů knihovny MFC třídy a záhlaví je relativně malé.Je speciální verze souboru (AFXV_DLL.H) stejně jako další záhlaví souboru (AFXDLL_.H) zařazena hlavní AFXWIN.H záhlaví.AFXDLL_.H záhlaví obsahuje CDynLinkLibrary třídy a další podrobnosti provádění obou _AFXDLL aplikace a knihovny DLL rozšíření standardu MFC.AFXDLLX.H záhlaví je k dispozici pro vytváření knihovny DLL rozšíření standardu MFC (viz výše podrobnosti).

Pravidelné zdroje do knihovny MFC MFC SRC mají některé dodatečné podmíněného kód pod _AFXDLL #ifdef.Soubor další zdroje (DLLINIT.CPP) obsahuje dodatečný kód inicializace knihovny DLL a dalších připevněte pro sdílenou verzi MFC.

K vytvoření sdílené verze MFC, jsou k dispozici další soubory.(Níže naleznete podrobnosti o vytvoření knihovny DLL.)

  • Dva.DEF soubory se používají pro export MFC DLL vstupních bodů pro ladění (MFCxxD.DEF) a uvolnit verze souboru DLL (MFCxx.DEF).

  • Aplikace.RC souboru (MFCDLL.RC) obsahuje všechny standardní prostředky MFC a VERSIONINFO prostředku pro knihovnu DLL.

  • A.Soubor CLW (MFCDLL.CLW) je k dispozici při procházení jednotka MFC třídy pomocí ClassWizard.Poznámka: Tato funkce není konkrétní verze DLL MFC.

hw85e4bb.collapse_all(cs-cz,VS.110).gifSpráva paměti

Aplikace MFCxx.DLL pomocí používá společný přidělování paměti poskytované MSVCRTxx.DLL sdílené knihovny DLL C runtime.Aplikace, všechny knihovny DLL rozšíření a také samotné knihovny DLL MFC použít toto přidělování sdílené paměti.Pomocí sdílené knihovny DLL pro přidělení paměti MFC knihovny DLL můžete přidělit paměť, která později uvolněna, aplikací nebo naopak.Protože aplikace a knihovny DLL musí použít stejné přidělování, by není potlačit globální C++ operator new nebo operator delete.Stejná pravidla se vztahují na zbytku rutiny přidělení paměti C Runtime (například malloc, realloc, beza další).

hw85e4bb.collapse_all(cs-cz,VS.110).gifŘadové číslovky a pojmenování DLL a třída __declspec(dllexport)

Doporučujeme nepoužívat class**__declspec(dllexport)** funkce kompilátoru jazyka C++.Místo toho je seznam vývozů součástí zdroje knihovny třídy (MFCxx.DEF a MFCxxD.DEF).Jsou exportovány pouze tyto vyberte sadu vstupních bodů (funkce a data).Jiné symboly, například MFC soukromé implementace funkce nebo třídy, nejsou exportovány všechny vývozy, provádí řadové bez názvu řetězec v tabulce název rezidenty a nerezidenty.

Pomocí class**__declspec(dllexport)** mohou být životaschopné alternativy pro vytváření knihoven DLL menší, ale z velké knihovny DLL jako MFC výchozí export mechanismus má účinnosti a kapacity limity.

Co to znamená všechny je, že jsme můžete balíček velké množství funkcí ve verzi MFCxx.DLL, která je pouze bez ohrožení mnohem spuštění nebo načtení rychlosti přibližně 800 KB.MFCxx.DLL by byly větší 100 kB nebyla tato technika používá.To také umožňuje přidat další vstupní body na konci.Soubor DEF bez ohrožení účinnosti rychlosti a velikosti exportu pomocí řadové umožnit jednoduchou správu verzí.Revize hlavní verze knihovny MFC třídy se změní název knihovny.Je MFC30.DLL je redistributable knihovny DLL obsahující verze 3.0 knihovna tříd MFC.Upgrade této knihovny DLL vyslovit hypotetická 3.1 MFC, bude název knihovny DLL MFC31.Knihovna DLL místo.Znovu Pokud upravíte zdrojový kód MFC vyrábět vlastní verze knihovny MFC, použijte jiný název (a pokud možno bez "MFC") v názvu.

Viz také

Další zdroje

Technické poznámky podle čísla

Technické poznámky podle kategorie