Udostępnij za pośrednictwem


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;
}

ksa99t88.collapse_all(pl-pl,VS.110).gifCo chcesz zrobić?

ksa99t88.collapse_all(pl-pl,VS.110).gifCo chcesz wiedzieć więcej?

Zobacz też

Koncepcje

Biblioteki DLL rozszerzenia