Inicializace rozšířené knihovny DLL
Protože rozšířené knihovny DLL nemají odvozený objekt CWinApp (normální knihovny DLL je mají), měli byste přidat inicializační a ukončovací kód pro funkci DllMain, kterou vytvoří průvodce knihovny MFC DLL.
Průvodce poskytuje následující kód pro rozšířené knihovny DLL. PROJNAME je v kódu zástupným symbolem pro název projekt.
#include "stdafx.h"
#include <afxdllx.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static AFX_EXTENSION_MODULE PROJNAMEDLL = { NULL, NULL };
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("PROJNAME.DLL Initializing!\n");
// Extension DLL one-time initialization
AfxInitExtensionModule(PROJNAMEDLL,
hInstance);
// Insert this DLL into the resource chain
new CDynLinkLibrary(Dll3DLL);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("PROJNAME.DLL Terminating!\n");
}
return 1; // ok
}
Vytvoření nového objektu CDynLinkLibrary během inicializace umožňuje rozšířené knihovně DLL exportovat objekty nebo zdroje CRuntimeClass do klientské aplikace.
Pokud budete používat vaši rozšířenou knihovnu DLL z jedné nebo více běžných knihoven DLL, je nutné exportovat inicializační funkci, která vytvoří objekt CDynLinkLibrary. Tato funkce musí být volána z každé běžné knihovny DLL, která používá rozšířenou knihovnu DLL. Příslušné místo pro volání této inicializační funkce je v členské funkci InitInstance odvozeného objektu CWinApp běžné knihovny DLL před tím, než použijete jakoukoliv exportovanou třídu nebo funkce rozšířené knihovny DLL.
V DllMain, kterou generuje průvodce knihovny MFC DLL, volání AfxInitExtensionModule zachytává běhové třídy modulu (struktury CRuntimeClass) stejně jako jeho "továrny objektu"(object factories) (objekty COleObjectFactory) pro použití, kdy je vytvářen objekt CDynLinkLibrary. Měli byste zkontrolovat vrácenou hodnotu AfxInitExtensionModule; Pokud je vrácena nulová hodnota z AfxInitExtensionModule, vrátí také nulu z vaší funkce DllMain.
Pokud bude vaše rozšířená knihovna DLL explicitně propojena se spustitelným souborem (to znamená spustitelný soubor volá AfxLoadLibrary, aby propojil knihovnu DLL), měli byste přidat volání AfxTermExtensionModule na DLL_PROCESS_DETACH. Tato funkce umožňuje knihovně MFC odstranit rozšíření DLL při každém odpojení procesu od rozšíření DLL (který se stane při ukončení procesu, nebo pokud je knihovna DLL uvolněna v důsledku volání AfxFreeLibrary). Pokud bude vaše rozšířená knihovna DLL implicitně propojena s aplikací, volání AfxTermExtensionModule není nutné.
Aplikace, které explicitně propojují rozšířené knihovny DLL, musí volat AfxTermExtensionModule při uvolňování knihovny DLL. Měli by také použít AfxLoadLibrary a AfxFreeLibrary (namísto funkcí LoadLibrary a FreeLibrary systému Win32) pokud aplikace používá více vláken. Použití AfxLoadLibrary a AfxFreeLibrary zajistí, že kód při spuštění a ukončení, který se vykoná, když je rozšířená knihovna DLL načtena a uvolněna, nepoškozuje globální stav knihovny MFC.
Protože je knihovna MFCx0.dll plně inicializována jakmile je volána DllMain, můžete přidělit paměť a volat funkce knihovny MFC v rámci DllMain (na rozdíl od 16bitové verze knihovny MFC).
Rozšířené knihovny DLL se mohou starat o multithreading zpracováním DLL_THREAD_ATTACH a DLL_THREAD_DETACH případně funkcí DllMain. Tyto případy jsou předány DllMain když jsou vlákna připojena a odpojena od knihovny DLL. Volání TlsAlloc, když je knihovna DLL připojovaná, jí umožňuje udržovat index místního úložného prostoru vlákna (thread local storage - protokol TLS) pro každé vlákno připojené ke knihovně DLL.
Všimněte si, že soubor hlaviček Afxdllx.h obsahuje zvláštní definice pro struktury používané v rozšířených knihovnách DLL, jako je například definice pro AFX_EXTENSION_MODULE a CDynLinkLibrary. Měli byste zahrnout tento hlavičkový soubor ve vašem rozšíření knihovny DLL.
Poznámka
Je důležité, že nemůžete definovat ani nedefinovat žádné z maker _AFX_NO_XXX v Stdafx.h. Další informace naleznete v článku znalostní báze "PRB: Problémy, které vznikají při definování _AFX_NO_XXX" (Q140751). Články znalostní báze Knowledge Base můžete najít v knihovně MSDN nebo na http://search.support.microsoft.com/.
Vzorová inicializační funkce, která zpracovává multithreading je součástí Použití místního úložného prostoru vlákna v dynamické knihovně ve Windows SDK. Všimněte si, že vzorek obsahuje funkci vstupního bodu nazvanou LibMain, ale měli byste pojmenovat tuto funkci jako DllMain, takže funguje s knihovnou MFC a běhovými knihovnami jazyka C.
Vzorek knihovny MFC DLLHUSK ukazuje použití inicializační funkce.
Co chcete udělat?
Co chcete vědět více?
Používání databáze, technologie OLE, a rozšíření soketů knihoven DLL v obvyklých knihovnách DLL
Funkční specifikace pro DllMain (sada SDK pro systém Windows)
Funkce vstupního bodu dynamické knihovny (sady SDK systému Windows)