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
AfxFindResourceHandle
NULL
yüklenemiyor.DllGetClassObject
,DllCanUnloadNow
ve öğesininUpdateRegistry
,Revoke
,RevokeAll
veRegisterAll
üye işlevleriCOleObjectFactory
, 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.dll
ve 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'nizeCWinApp::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ğindenMFCDxxD.dll
emin olun. Bu işlev parametre almaz ve döndürürvoid
.OLE desteği için
AfxOleInitModule
, normal MFC DLL'nize işlevineCWinApp::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ı öğesineAfxOleInitModule
eklememelisiniz.Yuva desteği için
AfxNetInitModule
içindeki normal MFC DLL'nizeCWinApp::InitInstance
bir ç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 CWinApp
kullanarak 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.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin