Používání databázových, OLE a soketových rozšiřujících knihoven MFC DLL v běžných knihovnách MFC DLL
Pokud používáte knihovnu DLL rozšíření MFC z běžné knihovny MFC DLL, není-li knihovna DLL rozšíření MFC připojena k CDynLinkLibrary
řetězci objektů běžné knihovny MFC DLL, můžete narazit na jeden nebo více souvisejících problémů. Vzhledem k tomu, že ladicí verze knihovny DLL databáze MFC, OLE a soketů podporují knihovny DLL, můžou se při používání těchto funkcí MFC zobrazit podobné problémy, i když explicitně nepoužíváte žádné vlastní knihovny DLL rozšíření MFC. Mezi příznaky patří mimo jiné:
Při pokusu o deserializaci objektu typu třídy definované v knihovně DLL rozšíření MFC, zpráva "Upozornění: Nelze načíst CYourClass z archivu. Třída není definována." zobrazí se v okně ladění TRACE a objekt se nepodaří serializovat.
Může dojít k výjimce označující chybnou třídu.
Prostředky uložené v knihovně DLL rozšíření MFC se nepodaří načíst, protože
AfxFindResourceHandle
vracíNULL
nebo nesprávné popisovač prostředků.DllGetClassObject
,DllCanUnloadNow
a ,Revoke
RevokeAll
aUpdateRegistry
, aRegisterAll
členské funkceCOleObjectFactory
selhání najít objekt pro vytváření tříd definovaný v knihovně DLL rozšíření MFC.AfxDoForAllClasses
nefunguje pro žádné třídy v knihovně DLL rozšíření MFC.Standardní databáze MFC, sokety nebo prostředky OLE se nenačtou. Například
AfxLoadString(AFX_IDP_SQL_CONNECT_FAIL)
vrátí prázdný řetězec, i když běžná knihovna MFC DLL správně používá databázové třídy MFC.
Řešením těchto problémů je vytvoření a export inicializační funkce v knihovně DLL rozšíření MFC, která vytvoří CDynLinkLibrary
objekt. Tuto inicializační funkci volejte přesně jednou z každé běžné knihovny MFC DLL, která používá rozšiřující knihovnu DLL knihovny MFC.
Podpora rozhraní MFC OLE, databáze MFC (nebo rozhraní DAO) nebo soketů MFC
Pokud používáte jakoukoli podporu rozhraní MFC OLE, databáze MFC (nebo rozhraní DAO) nebo soketů MFC v běžné knihovně MFC DLL, v uvedeném pořadí, knihovny MFC debug MFC extension MFCOxxD.dll
DLL , MFCDxxD.dll
a MFCNxxD.dll
(kde xx je číslo verze), jsou automaticky propojeny. Volání předdefinované inicializační funkce pro každou knihovnu DLL, kterou používáte:
Pro podporu databáze přidejte volání do
AfxDbInitModule
běžné knihovny MFC DLL ve svéCWinApp::InitInstance
funkci. Ujistěte se, že k tomuto volání dochází před voláním základní třídy nebo jakýmkoli přidaným kódem, který přistupuje kMFCDxxD.dll
. Tato funkce nepřijímá žádné parametry a vracívoid
.Pro podporu OLE přidejte volání do
AfxOleInitModule
běžné knihovny MFC DLL, která je jejíCWinApp::InitInstance
funkcí. FunkceCOleControlModule::InitInstance
už voláAfxOleInitModule
, takže pokud vytváříte ovládací prvek OLE a používáteCOleControlModule
, neměli byste toto volání přidávat .AfxOleInitModule
Pro podporu soketů přidejte volání do
AfxNetInitModule
běžné knihovny MFC DLL vCWinApp::InitInstance
souboru .
Vydané buildy knihoven MFC DLL a aplikací nepoužívají samostatné knihovny DLL pro podporu databáze, soketů nebo OLE. Je však bezpečné volat tyto inicializační funkce v režimu vydání.
CDynLinkLibrary – objekty
Během každé operace uvedené na začátku tohoto článku musí mfc vyhledat konkrétní hodnotu nebo objekt. Například během deserializace musí MFC prohledávat všechny aktuálně dostupné třídy runtime tak, aby odpovídaly objektům v archivu se správnou třídou runtime.
V rámci těchto hledání mfc prohledá všechny knihovny DLL rozšíření MFC, které se používají, procházením řetězce CDynLinkLibrary
objektů. CDynLinkLibrary
objekty se automaticky připojují ke řetězu během jejich výstavby a jsou vytvořeny jednotlivými rozšiřujícími knihovnami MFC DLL zase během inicializace. Každý modul (aplikace nebo běžná knihovna MFC DLL) má svůj vlastní řetěz CDynLinkLibrary
objektů.
Aby knihovna DLL rozšíření MFC dostala kabel do řetězu CDynLinkLibrary
, musí vytvořit CDynLinkLibrary
objekt v kontextu každého modulu, který používá rozšiřující knihovnu DLL knihovny MFC. Chcete-li použít knihovnu DLL rozšíření MFC v běžných knihovnách MFC DLL, musí knihovna DLL rozšíření poskytnout exportovanou inicializační funkci, která vytvoří CDynLinkLibrary
objekt. Každá běžná knihovna MFC DLL, která používá rozšiřující knihovnu DLL knihovny MFC, musí volat exportovanou inicializační funkci.
Pokud budete používat pouze rozšiřující knihovnu DLL knihovny MFC z aplikace MFC a nikdy z běžné knihovny MFC DLL, stačí vytvořit CDynLinkLibrary
objekt ve funkci KNIHOVNY DllMain
DLL rozšíření MFC. Je to, co dělá kód knihovny MFC DLL Průvodce knihovnou MFC dll. Při implicitní načítání knihovny DLL rozšíření MFC se DllMain
načte a spustí před spuštěním aplikace. Všechny CDynLinkLibrary
vytváření jsou připojeny do výchozího řetězu, který knihovna MFC DLL vyhrazuje pro aplikaci MFC.
Je špatné mít v libovolném řetězci více CDynLinkLibrary
objektů z jedné knihovny DLL rozšíření MFC. Platí to zejména v případě, že knihovna DLL rozšíření MFC může být dynamicky uvolněna z paměti. Nevolejte funkci inicializace více než jednou z jednoho modulu.
Ukázka kódu
Tento ukázkový kód předpokládá, že běžná knihovna MFC DLL implicitně odkazuje na knihovnu DLL rozšíření MFC. Pokud chcete implicitně propojit knihovnu importu (soubor LIB) knihovny MFC s příponou DLL při sestavování běžné knihovny MFC DLL.
Následující řádky by měly být ve zdroji knihovny DLL rozšíření MFC:
// YourExtDLL.cpp:
// standard MFC extension DLL routines
#include "afxdllx.h"
static AFX_EXTENSION_MODULE extensionDLL;
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// MFC extension DLL one-time initialization
if (!AfxInitExtensionModule(extensionDLL, hInstance))
return 0;
}
return 1; // ok
}
// Exported DLL initialization is run in context of
// application or regular MFC DLL
extern "C" void WINAPI InitYourExtDLL()
{
// create a new CDynLinkLibrary for this app
new CDynLinkLibrary(extensionDLL);
// add other initialization here
}
Nezapomeňte exportovat funkci InitYourExtDLL . Můžete ho použít __declspec(dllexport)
nebo exportovat do souboru DEF pro knihovnu DLL, jak je znázorněno zde:
// YourExtDLL.Def:
LIBRARY YOUREXTDLL
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD SINGLE
EXPORTS
InitYourExtDLL
Přidejte volání InitInstance
člena CWinApp
-odvozeného objektu v každé běžné MFC DLL pomocí knihovny MFC rozšíření DLL:
// YourRegularDLL.cpp:
class CYourRegularDLL : public CWinApp
{
public:
virtual BOOL InitInstance(); // Initialization
virtual int ExitInstance(); // Termination
// nothing special for the constructor
CYourRegularDLL(LPCTSTR pszAppName) : CWinApp(pszAppName) { }
};
BOOL CYourRegularDLL::InitInstance()
{
// any DLL initialization goes here
TRACE0("YOUR regular MFC DLL initializing\n");
// wire any MFC extension DLLs into CDynLinkLibrary chain
InitYourExtDLL();
return TRUE;
}