Przy użyciu bazy danych OLE i biblioteki DLL rozszerzenia Sockets w regularnych biblioteki DLL.
Podczas korzystania z rozszerzeniem DLL z regularnych biblioteki DLL, jeśli rozszerzenie DLL nie jest dostępna w CDynLinkLibrary obiektu łańcucha regularnych biblioteki DLL może działać na jeden lub więcej zestaw problemów związanych.Ponieważ wersje debug MFC bazy danych OLE i gniazd obsługują bibliotek DLL są implementowane jako rozszerzenie DLL, może zostać wyświetlony podobne problemy, jeśli używasz MFC tych funkcji, nawet jeśli nie jawnie używasz żadnego własne rozszerzenie DLL.Niektóre symptomy są:
Podczas próby deserializacji obiektu typu klasy zdefiniowane w rozszerzeniu DLL, wiadomość "Ostrzeżenie: nie można załadować CYourClass z archiwum.Klasa nie jest zdefiniowany.", który pojawia się w oknie Debugowanie śledzenia i obiektu nie można serializować.
Wskazując bad klasy może być wyjątek.
Zasobów przechowywanych w bibliotece DLL rozszerzenia nie można załadować, ponieważ AfxFindResourceHandle zwraca NULL lub zasób nieprawidłowe dojście.
DllGetClassObject, DllCanUnloadNowi UpdateRegistry, Revoke, RevokeAll, i RegisterAll funkcji elementów członkowskich z COleObjectFactory nie można zlokalizować fabryki klasy zdefiniowane w bibliotece DLL rozszerzenia.
AfxDoForAllClassesnie działa dla wszystkich klas w bibliotece DLL rozszerzenia.
Bazę standardową MFC, gniazda lub zasoby OLE nie można załadować.Na przykład AfxLoadString(AFX_IDP_SQL_CONNECT_FAIL) zwraca ciąg pusty, nawet w przypadku, gdy regularne DLL jest poprawnie przy użyciu klas MFC bazy danych.
Rozwiązanie tych problemów jest aby utworzyć i wyeksportować funkcję inicjowania w rozszerzeniu DLL, która tworzy CDynLinkLibrary obiektu.Wywołanie tej funkcji inicjacji dokładnie raz z każdego regularnych biblioteki DLL, która korzysta z biblioteki DLL rozszerzenia.
MFC OLE, bazy danych MFC (lub obiektów DAO), lub wsparcie Sockets MFC
Jeśli używasz jakichkolwiek MFC OLE, bazy danych MFC (lub DAO) lub MFC gniazd obsługują w bibliotece DLL regularnych, odpowiednio, rozszerzenie debugowania MFC DLL MFCOxxD.dll, MFCDxxD.dll i MFCNxxD.dll (gdzie xx jest numerem wersji) są połączone automatycznie.Należy wywołać funkcję inicjalizacji wstępnie zdefiniowanych dla każdego z tych bibliotek DLL, które są używane.
Obsługę bazy danych, należy dodać wywołanie AfxDbInitModule do biblioteki DLL regularne CWinApp::InitInstance funkcji.Upewnij się, to wywołanie występuje przed każde wywołanie klasy base lub wszelkie dodane kod, który uzyskuje dostęp do MFCDxxD.dll.Ta funkcja nie ma parametrów i zwraca void.
Obsługę OLE, należy dodać wywołanie AfxOleInitModule do biblioteki DLL regularne CWinApp::InitInstance.Należy zauważyć, że COleControlModule InitInstance działać wywołania AfxOleInitModule już, więc jeśli budowana jest formantem OLE i korzystają z COleControlModule, nie należy dodawać tego wywołania AfxOleInitModule.
Dla wsparcia Sockets dodać wywołanie AfxNetInitModule do biblioteki DLL regularne CWinApp::InitInstance.
Zauważ, że dopuszczenie kompilacjach MFC DLL i aplikacje nie używają oddzielnych bibliotek DLL dla bazy danych, gniazda, lub obsługi OLE.Jednakże jest bezpiecznie wywoływać te funkcje inicjowania w trybie wersji.
Obiekty CDynLinkLibrary
Podczas każdej operacji wymienionych na początku tego tematu MFC musi wyszukać żądaną wartość lub obiektu.Na przykład podczas deserializacji, MFC musi przeszukiwać wszystkie aktualnie dostępne klasy run-time do obiektów w archiwum z ich właściwego klasy uruchomieniowej.
Jako część z tych wyszukiwań, MFC przegląda DLL rozszerzenia używane przez idzie w łańcuchu CDynLinkLibrary obiektów.CDynLinkLibrary obiekty automatycznie dołączać do łańcucha, podczas ich budowy i są tworzone przez każde rozszerzenie DLL z kolei podczas inicjowania.Ponadto każdy moduł (aplikacji lub regularnych DLL) ma swój własny łańcucha CDynLinkLibrary obiektów.
Z rozszerzeniem DLL, aby uzyskać połączonymi CDynLinkLibrary w łańcuchu, należy utworzyć CDynLinkLibrary obiektu w kontekście każdy moduł, który używa biblioteki DLL rozszerzenia.W związku z tym, rozszerzenie DLL będzie do używania z regularnych biblioteki DLL, musi zapewniać funkcji eksportowanych inicjowania, który tworzy CDynLinkLibrary obiektu.Każdy regularnych biblioteki DLL, która wykorzystuje rozszerzenie DLL musi wywoływać funkcję inicjalizacji wywożonych.
Jeśli rozszerzenie DLL ma być używane z aplikacji MFC (.exe) i nigdy nie z regularnych biblioteki DLL, a następnie wystarczy utworzyć CDynLinkLibrary obiektu w rozszerzeniu DLL's DllMain.Jest to, co robi kod biblioteki DLL rozszerzenia MFC DLL kreatora.Podczas ładowania biblioteki DLL rozszerzenia niejawnie, DllMain ładuje i wykonuje przed kiedykolwiek uruchomieniem aplikacji.Każdy CDynLinkLibrary intelektu są połączone do łańcucha domyślne, że biblioteki MFC DLL rezerwuje się dla aplikacji MFC.
Zauważ, że zły pomysł mają wiele CDynLinkLibrary obiekty z jednej biblioteki DLL rozszerzenia jednego łańcucha, zwłaszcza, jeśli biblioteka DLL rozszerzenia będzie dynamicznie usuwane z pamięci.Nie wywołuj funkcję inicjowania więcej niż raz z dowolnego jednego modułu.
Przykładowy kod
Kod ten zakłada, że regularne DLL jest niejawnie łączenie z biblioteki DLL rozszerzenia.Można to osiągnąć przez połączenie z biblioteki import (lib) z rozszerzeniem DLL podczas konstruowania regularnych DLL.
Następujące wiersze powinny być w źródle biblioteki DLL rozszerzenia:
// YourExtDLL.cpp:
// standard MFC extension DLL routines
#include "afxdllx.h"
static AFX_EXTENSION_MODULE NEAR extensionDLL = { NULL, NULL };
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// 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 DLL
extern "C" void WINAPI InitYourExtDLL()
{
// create a new CDynLinkLibrary for this app
new CDynLinkLibrary(extensionDLL);
// add other initialization here
}
Należy upewnić się, że wywóz InitYourExtDLL funkcji.Można to zrobić stosując opcję __declspec(dllexport) lub w pliku .def biblioteki DLL w następujący sposób:
// YourExtDLL.Def:
LIBRARY YOUREXTDLL
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD SINGLE
EXPORTS
InitYourExtDLL
Dodać wywołanie InitInstance członek CWinApp-pochodzących z obiektów w każdej regularnych biblioteki DLL przy użyciu biblioteki DLL rozszerzenia:
// 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 DLL initializing\n");
// wire any extension DLLs into CDynLinkLibrary chain
InitYourExtDLL();
return TRUE;
}