Aracılığıyla paylaş


Normal MFC DLL'lerinde Veritabanı, OLE ve Yuva MFC uzantısı DLL'leri Kullanma

Normal bir MFC DLL'sinden MFC uzantı DLL'sini kullanırken, MFC uzantı DLL'i normal MFC DLL'sinin nesne zincirine CDynLinkLibrary bağlı değilse, ilgili bir veya daha fazla sorunla karşılaşabilirsiniz. MFC Veritabanı, OLE ve Yuva desteği DLL'lerinin hata ayıklama sürümleri MFC uzantısı DLL'leri olarak uygulandığından, kendi MFC uzantı DLL'lerinizden herhangi birini açıkça kullanmasanız bile bu MFC özelliklerini kullanıyorsanız benzer sorunlar görebilirsiniz. Bazı belirtiler şunlardır:

  • MFC uzantısı DLL'sinde tanımlanan sınıf türünde bir nesnenin seri durumdan çıkarılması denenirken, "Uyarı: CYourClass arşivden yüklenemiyor. Sınıf tanımlanmadı." ifadesi TRACE hata ayıklama penceresinde görüntülenir ve nesne serileştirilemez.

  • Hatalı sınıfı gösteren bir özel durum oluşturulabilir.

  • MFC uzantısı DLL'sinde depolanan kaynaklar döndürdüğünden veya yanlış kaynak tutamacı döndürdüğünden AfxFindResourceHandleNULL yüklenemiyor.

  • DllGetClassObject, DllCanUnloadNowve öğesinin UpdateRegistry, Revoke, RevokeAllve RegisterAll üye işlevleri COleObjectFactory , MFC uzantısı DLL'sinde tanımlanan bir sınıf fabrikasını bulamıyor.

  • AfxDoForAllClasses MFC uzantısı DLL'sindeki hiçbir sınıf için çalışmaz.

  • Standart MFC veritabanı, yuvalar veya OLE kaynakları yüklenemedi. Örneğin, AfxLoadString(AFX_IDP_SQL_CONNECT_FAIL) normal MFC DLL'sinin MFC Veritabanı sınıflarını düzgün bir şekilde kullandığında bile boş bir dize döndürür.

Bu sorunların çözümü, bir nesne oluşturan CDynLinkLibrary MFC uzantısı DLL'sinde bir başlatma işlevi oluşturmak ve dışarı aktarmaktır. MFC uzantısı DLL'sini kullanan her normal MFC DLL'sinden bu başlatma işlevini tam olarak bir kez çağırın.

MFC OLE, MFC Veritabanı (veya DAO) veya MFC Yuva Desteği

Normal MFC DLL'nizde sırasıyla herhangi bir MFC OLE, MFC Veritabanı (veya DAO) veya MFC Yuva desteği kullanıyorsanız, MFC hata ayıklama MFC uzantısı DLL'leri MFCOxxD.dll, MFCDxxD.dllve MFCNxxD.dll (burada xx sürüm numarasıdır) otomatik olarak bağlanır. Kullanmakta olduğunuz DLL'lerin her biri için önceden tanımlanmış bir başlatma işlevi çağırın:

  • Veritabanı desteği için AfxDbInitModule , işlevinde normal MFC DLL'nize CWinApp::InitInstance bir çağrı ekleyin. Bu çağrının herhangi bir temel sınıf çağrısından veya öğesine erişen ek kodlardan önce gerçekleştiğinden MFCDxxD.dllemin olun. Bu işlev parametre almaz ve döndürür void.

  • OLE desteği için AfxOleInitModule , normal MFC DLL'nize işlevine CWinApp::InitInstance bir çağrı ekleyin. COleControlModule::InitInstance İşlev zaten çağırırAfxOleInitModule, bu nedenle bir OLE denetimi oluşturup kullanıyorsanızCOleControlModule, bu çağrıyı öğesine AfxOleInitModuleeklememelisiniz.

  • Yuva desteği için AfxNetInitModule içindeki normal MFC DLL'nize CWinApp::InitInstancebir çağrı ekleyin.

MFC DLL'lerinin ve uygulamalarının yayın derlemeleri veritabanı, yuvalar veya OLE desteği için ayrı DLL'ler kullanmaz. Ancak bu başlatma işlevlerini yayın modunda çağırmak güvenlidir.

CDynLinkLibrary Nesneleri

Bu makalenin başında bahsedilen her işlem sırasında MFC'nin belirli bir değeri veya nesneyi araması gerekir. Örneğin, seri durumdan çıkarma sırasında MFC'nin arşivdeki nesneleri uygun çalışma zamanı sınıfıyla eşleştirmek için kullanılabilir durumdaki tüm çalışma zamanı sınıflarını araması gerekir.

MFC, bu aramaların bir parçası olarak, bir nesne zincirini CDynLinkLibrary yürüyerek kullanımdaki tüm MFC uzantı DLL'lerini tarar. CDynLinkLibrary nesneleri, oluşturma sırasında bir zincire otomatik olarak bağlanır ve başlatma sırasında her MFC uzantısı DLL'i tarafından oluşturulur. Her modülün (uygulama veya normal MFC DLL) kendi nesne zinciri CDynLinkLibrary vardır.

Bir MFC uzantı DLL'sinin zincire CDynLinkLibrary bağlanabilmesi için, MFC uzantı DLL'sini kullanan her modül bağlamında bir CDynLinkLibrary nesne oluşturması gerekir. Normal MFC DLL'lerinde MFC uzantı DLL'sini kullanmak için, uzantı DLL'sinin bir nesne oluşturan dışarı aktarılan bir CDynLinkLibrary başlatma işlevi sağlaması gerekir. MFC uzantısı DLL'sini kullanan her normal MFC DLL'sinin dışarı aktarılan başlatma işlevini çağırması gerekir.

Bir MFC uygulamasından yalnızca MFC uzantı DLL'sini kullanacak ve hiçbir zaman normal bir MFC DLL'sinden kullanmazsanız, nesneyi MFC uzantısı DLL DllMain işlevinde oluşturmak CDynLinkLibrary yeterlidir. MFC DLL Sihirbazı MFC uzantısı DLL kodu bunu yapar. MFC uzantı DLL'sini örtük olarak yüklerken, DllMain uygulama başlatılmadan önce yüklenir ve yürütülür. Tüm CDynLinkLibrary oluşturma işlemleri, MFC DLL'sinin bir MFC uygulaması için ayırdığını varsayılan bir zincire bağlanır.

Tek bir zincirde bir MFC uzantı DLL'sinden birden çok CDynLinkLibrary nesne olması kötü bir fikirdir. MFC uzantısı DLL'sinin bellekten dinamik olarak kaldırılmış olması özellikle doğrudur. Başlatma işlevini bir modülden birden çok kez çağırmayın.

Örnek Kod

Bu örnek kod, normal MFC DLL'sinin MFC uzantısı DLL'sine örtük olarak bağlandığını varsayar. Örtük olarak bağlanmak için, normal MFC DLL'sini oluştururken MFC uzantısı DLL'sinin içeri aktarma kitaplığına (LIB dosyası) bağlanın.

Aşağıdaki satırlar MFC uzantı DLL'sinin kaynağında olmalıdır:

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

InitYourExtDLL işlevini dışarı aktarmayı unutmayın. burada gösterildiği gibi , kullanabilir __declspec(dllexport)veya DLL'nizin DEF dosyasında dışarı aktarabilirsiniz:

// YourExtDLL.Def:
LIBRARY      YOUREXTDLL
CODE         PRELOAD MOVEABLE DISCARDABLE
DATA         PRELOAD SINGLE
EXPORTS
    InitYourExtDLL

MFC uzantı DLL'sini CWinAppkullanarak her normal MFC DLL'sindeki türetilmiş nesnenin üyesine bir çağrı InitInstance ekleyin:

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

Ne yapmak istiyorsunuz?

Ne hakkında daha fazla bilgi edinmek istiyorsunuz?

Ayrıca bkz.

MFC uzantısı DLL’leri