Używanie bibliotek DLL baz danych, OLE i rozszerzeń gniazd w zwykłych bibliotekach DLL
Jeżeli podczas korzystania z rozszerzeniem DLL z regularnych biblioteki DLL, rozszerzenie DLL nie jest dostępna w CDynLinkLibrary obiekt łańcucha regularnych biblioteki dll, może działać w co najmniej jednym zestawem problemów pokrewnych.Ponieważ wersje debugowania bazy danych MFC, OLE i gniazd obsługują pliki dll są implementowane jako biblioteki DLL rozszerzenia, może zostać wyświetlony oferuje podobne problemy, jeśli używasz tych MFC, nawet jeśli nie jawnie używasz żadnego z własnych bibliotek DLL rozszerzeń.Niektóre objawy są:
Kiedy podjęto próbę deserializacji obiektu typu klasy zdefiniowane w rozszerzeniu DLL, wiadomość "Ostrzeżenie: nie można załadować CYourClass z archiwum.Klasa nie jest zdefiniowana."pojawia się w oknie debugowania śledzenia i obiektu nie powiedzie się do serializacji.
Wykazującą klasę zły może się wyjątek.
Zasobów przechowywanych w bibliotece DLL rozszerzenia nie można załadować, ponieważ AfxFindResourceHandle zwraca wartości NULL lub zasobów nieprawidłowe dojście.
DllGetClassObject, DllCanUnloadNowi UpdateRegistry, Revoke, RevokeAll, i RegisterAll funkcji elementów członkowskich z COleObjectFactory mieć problemy z lokalizowaniem fabryki klasy zdefiniowane w bibliotece DLL rozszerzenia.
AfxDoForAllClassesnie działa w przypadku wszystkich klas w bibliotece DLL rozszerzenia.
Bazę standardową MFC, gniazda lub zasobów OLE nie będą ładowane.Na przykład AfxLoadString(AFX_IDP_SQL_CONNECT_FAIL) zwraca pusty ciąg, nawet wtedy, gdy regularne DLL jest poprawnie przy użyciu klasami baz danych MFC.
Rozwiązanie tych problemów jest, aby utworzyć i wyeksportować funkcję inicjowania w bibliotece DLL, która tworzy rozszerzenia CDynLinkLibrary obiektu.Wywołać tę funkcję inicjalizacji dokładnie raz z każdym regularnych biblioteki DLL, która korzysta z biblioteki DLL rozszerzenia.
MFC OLE, bazy danych MFC (lub obiektów DAO), lub MFC nasadki pomocy technicznej
Jeśli używasz żadnych MFC OLE, MFC bazy danych (lub DAO) lub MFC Sockets, obsługa w bibliotece DLL regularnych, odpowiednio, rozszerzenie debugowania biblioteki MFC DLL MFCOxxD.dll, MFCDxxD.dll i MFCNxxD.dll (gdzie xx jest numerem wersji) są automatycznie połączone.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 regularnych biblioteki DLL CWinApp::InitInstance funkcji.Upewnij się, to wywołanie jest wcześniejsza niż każde wywołanie klasa bazowa lub wszelkie dodane kod, który uzyskuje dostęp do MFCDxxD.dll.Ta funkcja nie ma parametrów i zwraca typ void.
Obsługę OLE, dodać wywołanie AfxOleInitModule do regularnych biblioteki DLL CWinApp::InitInstance.Należy zauważyć, że COleControlModule InitInstance wywołania funkcji AfxOleInitModule już, więc jeśli tworzysz formantu OLE i są za pomocą COleControlModule, nie należy dodawać tego wywołania AfxOleInitModule.
Dla wsparcia Sockets, dodać wywołanie AfxNetInitModule do regularnych biblioteki DLL CWinApp::InitInstance.
Zauważ, że buduje wersji bibliotek MFC dll i aplikacji należy używać oddzielnych bibliotek DLL dla bazy danych, gniazda, lub obsługi OLE.To może wywołać funkcje te inicjowania w trybie release.
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 wykonywania odpowiadają obiekty w archiwum z ich właściwego wykonania klasy.
W ramach tych wyszukiwań, MFC przeszukuje wszystkie dll rozszerzenia w użyciu pieszo łańcucha CDynLinkLibrary obiektów.CDynLinkLibrary obiekty automatycznie dołączyć do łańcucha podczas ich budowy i są tworzone przez każde rozszerzenie DLL z kolei podczas inicjowania.Ponadto, każdy moduł (aplikacja lub biblioteka DLL regularnych) ma swój własny łańcuch CDynLinkLibrary obiektów.
Z rozszerzeniem DLL, aby uzyskać połączonymi w CDynLinkLibrary łańcucha, należy utworzyć CDynLinkLibrary obiektu w kontekście każdego modułu, który korzysta z biblioteki DLL rozszerzenia.W związku z tym, jeżeli rozszerzenie DLL będzie używany z regularnych bibliotek DLL, musi ono zapewnić błędu funkcji inicjowania wywożonych, który tworzy CDynLinkLibrary obiektu.Co regularne biblioteki DLL, która wykorzystuje rozszerzenie DLL musi wywołać funkcję inicjalizacji eksportowanych.
Jeśli rozszerzenie DLL jest tylko będzie używany z aplikacji MFC (.exe) i nigdy nie z regularnych biblioteki DLL, a następnie jest wystarczający dla stworzenia CDynLinkLibrary obiektu w bibliotece DLL rozszerzenia 's DllMain.Jest to, czy rozszerzenie MFC DLL Kreatora kod biblioteki DLL.Podczas ładowania biblioteki DLL rozszerzenia niejawnie, DllMain ładuje i uruchamia przed uruchomieniem kiedykolwiek aplikacji.Wszelkie CDynLinkLibrary kreacji są podłączone do łańcucha domyślne że biblioteki MFC DLL rezerw na aplikacji MFC.
Należy zauważyć, że to zły pomysł, aby mieć wielu CDynLinkLibrary z jednej biblioteki DLL rozszerzenia w dowolnym jednym łańcuchu obiekty, zwłaszcza, jeśli biblioteka DLL rozszerzenia będzie dynamicznie usuwane z pamięci.Nie wywołuj funkcję inicjalizacji więcej niż jeden raz z dowolnego jednego modułu.
Przykładowy kod
Ten przykładowy kod zakłada, że regularne DLL jest niejawnie łączenia z biblioteki DLL rozszerzenia.Można to osiągnąć przez łączenie do import biblioteki (lib) z biblioteki DLL rozszerzenia podczas konstruowania regularnych biblioteki DLL.
Następujące wiersze powinny być źródłem 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
}
Pamiętaj wyeksportować InitYourExtDLL funkcji.Można to zrobić za pomocą __declspec(dllexport) lub w pliku o rozszerzeniu 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-pochodnych obiektu w każdym regularnych 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;
}