Aracılığıyla paylaş


MFC uzantısı DLL’leri

MFC uzantı DLL'i, genellikle mevcut Microsoft Foundation Sınıf Kitaplığı sınıflarından türetilen yeniden kullanılabilir sınıfları uygulayan bir DLL'dir.

MFC uzantı DLL'sinin özellikleri ve gereksinimleri şunlardır:

  • İstemci yürütülebilir dosyası tanımlı olarak _AFXDLL derlenmiş bir MFC uygulaması olmalıdır.

  • MFC uzantısı DLL'leri, MFC'ye dinamik olarak bağlı normal bir MFC DLL'leri tarafından da kullanılabilir.

  • MFC uzantısı DLL'leri tanımlı olarak _AFXEXT derlenmelidir. Bu da tanımlanmaya zorlar _AFXDLL ve MFC üst bilgi dosyalarından doğru bildirimlerin çekilmesini sağlar. Ayrıca, DLL'yi oluştururken olarak __declspec(dllexport) tanımlanmasını sağlarAFX_EXT_CLASS. Bu, MFC uzantı DLL'nizdeki sınıfları bildirmek için bu makroyu kullanıyorsanız gereklidir.

  • MFC uzantısı DLL'leri, öğesinden CWinApptüretilen bir sınıfın örneğini oluşturmamalı, ancak bu nesneyi sağlamak için istemci uygulamasına (veya DLL'ye) bağımlı olmalıdır.

  • Ancak MFC uzantısı DLL'leri bir DllMain işlev sağlamalı ve gerekli başlatmaları orada yapmalıdır.

Uzantı DLL'leri, MFC'nin dinamik bağlantı kitaplığı sürümü (MFC'nin paylaşılan sürümü olarak da bilinir) kullanılarak oluşturulur. Yalnızca MFC'nin paylaşılan sürümüyle oluşturulan MFC yürütülebilir dosyaları (uygulamalar veya normal MFC DLL'leri) bir MFC uzantısı DLL kullanabilir. hem istemci uygulaması hem de MFC uzantı DLL'sinin aynı MFCx0.dll sürümünü kullanması gerekir. MFC uzantı DLL'siyle, MFC'den yeni özel sınıflar türetebilir ve ardından DLL'nizi çağıran uygulamalara bu genişletilmiş MFC sürümünü sunabilirsiniz.

Uzantı DLL'leri, MFC türetilmiş nesneleri uygulama ve DLL arasında geçirmek için de kullanılabilir. Geçirilen nesneyle ilişkili üye işlevleri, nesnenin oluşturulduğu modülde bulunur. MFC'nin paylaşılan DLL sürümü kullanılırken bu işlevler düzgün şekilde dışarı aktarıldığından, MFC veya MFC türetilmiş nesne işaretçilerini bir uygulama ile yüklediği MFC uzantısı DLL'leri arasında serbestçe geçirebilirsiniz.

MFC uzantısı DLL'leri, MFC'nin paylaşılan sürümünü, uygulamanın MFC'nin paylaşılan DLL sürümünü kullandığı gibi kullanır ve dikkat edilmesi gereken birkaç nokta daha vardır:

  • Türetilmiş bir CWinAppnesnesi yok. İstemci uygulamasının CWinApptüretilmiş nesnesiyle çalışmalıdır. Bu, istemci uygulamasının ana ileti pompasına, boşta döngüsüne vb. sahip olduğu anlamına gelir.

  • işlevini çağırır AfxInitExtensionModuleDllMain . Bu işlevin dönüş değeri denetlenmelidir. değerinden AfxInitExtensionModulesıfır değer döndürülürse işlevinizden DllMain 0 döndürür.

  • MFC uzantısı DLL'si nesneleri veya kaynakları uygulamaya aktarmak CRuntimeClass istiyorsa başlatma sırasında bir CDynLinkLibrary nesnesi oluşturur.

MFC'nin 4.0 sürümünden önce, bu tür DLL'ler AFXDLL olarak adlandırılıyordu. AFXDLL, DLL oluşturulurken tanımlanan önişlemci simgesine başvurur _AFXDLL .

MFC'nin paylaşılan sürümü için içeri aktarma kitaplıkları, MFC DLL'leri için adlandırma kuralları bölümünde açıklanan kurala göre adlandırılır. Visual Studio, MFC DLL'lerinin önceden oluşturulmuş sürümlerinin yanı sıra uygulamalarınızla birlikte kullanabileceğiniz ve dağıtabileceğiniz bir dizi MFC dışı DLL sağlar. Bunlar, Program Files\Microsoft Visual Studio klasörüne yüklenen Redist.txt dosyasında belgelenmiştir.

Bir .def dosyası kullanarak dışarı aktarıyorsanız, üst bilgi dosyanızın başına ve sonuna aşağıdaki kodu yerleştirin:

#undef AFX_DATA
#define AFX_DATA AFX_EXT_DATA
// <body of your header file>
#undef AFX_DATA
#define AFX_DATA

Bu dört satır, kodunuzun bir MFC uzantısı DLL'i için doğru derlendiğinden emin olun. Bu dört satırın dışında bırakılması DLL'nizin yanlış derlenip bağlanmasına neden olabilir.

MFC veya MFC türetilmiş nesne işaretçisini bir MFC DLL'sine veya MFC DLL'sinden geçirmeniz gerekiyorsa, DLL bir MFC uzantısı DLL olmalıdır. Geçirilen nesneyle ilişkili üye işlevleri, nesnenin oluşturulduğu modülde bulunur. MFC'nin paylaşılan DLL sürümü kullanılırken bu işlevler düzgün şekilde dışarı aktarıldığından, MFC veya MFC türetilmiş nesne işaretçilerini bir uygulama ile yüklediği MFC uzantısı DLL'leri arasında serbestçe geçirebilirsiniz.

C++ ad düzenleme ve dışarı aktarma sorunları nedeniyle, MFC uzantısı DLL'sinden dışarı aktarma listesi, farklı platformlar için aynı DLL ve DLL'lerin hata ayıklama ve perakende sürümleri arasında farklı olabilir. Perakende MFCx0.dll dosyasının yaklaşık 2.000 dışarı aktarılan giriş noktası vardır; Hata ayıklama MFCx0D.dll dosyasında yaklaşık 3.000 dışarı aktarılan giriş noktası vardır.

Bellek Yönetimi

bir istemci uygulamasının adres alanına yüklenen MFCx0.dll ve tüm MFC uzantısı DLL'leri aynı uygulamadaymış gibi aynı bellek ayırıcısını, kaynak yüklemesini ve diğer MFC genel durumlarını kullanır. MFC DLL olmayan kitaplıklar ve normal MFC DLL'leri tam tersini yaptığı ve her DLL'nin kendi bellek havuzundan ayırması nedeniyle bu önemli bir durumdur.

Bir MFC uzantı DLL'i bellek ayırırsa, bu bellek uygulama tarafından ayrılan diğer tüm nesnelerle serbestçe kesişebilir. Ayrıca, MFC'ye dinamik olarak bağlanan bir uygulama başarısız olursa, işletim sisteminin korunması DLL'yi paylaşan diğer tüm MFC uygulamalarının bütünlüğünü korur.

Benzer şekilde, kaynakları yüklenecek geçerli yürütülebilir dosya gibi diğer genel MFC durumları da istemci uygulaması ve tüm MFC uzantısı DLL'leri ile MFCx0.dll'nin kendisi arasında paylaşılır.

Kaynakları ve Sınıfları Paylaşma

Kaynakları dışarı aktarma işlemi bir kaynak listesi aracılığıyla yapılır. Her uygulama, CDynLinkLibrary nesnelerinin tek bağlantılı bir listesini içerir. Kaynak ararken, kaynakları yükleyen standart MFC uygulamalarının çoğu önce geçerli kaynak modülüne (AfxGetResourceHandle) bakar ve kaynak bulunamazsa, istenen kaynağı yüklemeye çalışan CDynLinkLibrary nesnelerinin listesi görüntülenir.

Listede yürümenin, biraz daha yavaş olması ve kaynak kimliği aralıklarının yönetilmesini gerektirmesi dezavantajları vardır. Birkaç MFC uzantısı DLL'sine bağlanan bir istemci uygulamasının DLL örneği tanıtıcısını belirtmek zorunda kalmadan DLL tarafından sağlanan herhangi bir kaynağı kullanabilmesi avantajına sahiptir. AfxFindResourceHandle , belirli bir eşleşmeyi aramak için kaynak listesinde yürümek için kullanılan bir API'dir. Kaynağın adını ve türünü alır ve ilk bulunduğu kaynak tutamacını (veya NULL) döndürür.

Listede gezinmek ve yalnızca belirli bir yerden kaynakları yüklemek istemiyorsanız, eski tanıtıcıyı kaydetmek ve AfxSetResourceHandle yeni tanıtıcıyı ayarlamak için ve işlevlerini AfxGetResourceHandle kullanın. İstemci uygulamasına dönmeden önce eski kaynak tanıtıcısını geri yüklemeyi unutmayın. Menüyü açıkça yüklemek için bu yaklaşımı kullanma örneği için bkz. MFC örnek DLLHUSK içindeki Testdll2 .cpp.

MFC adı verilen MFC nesnelerinin dinamik olarak oluşturulması benzerdir. MFC nesne seri durumdan çıkarma mekanizmasının CRuntimeClass , daha önce depolananlara göre gerekli türde C++ nesnelerini dinamik olarak oluşturarak yeniden oluşturabilmesi için tüm nesnelerin kayıtlı olması gerekir.

MFC örnek DLLHUSK örneğinde, liste şuna benzer:

head ->   DLLHUSK.EXE   - or -   DLLHUSK.EXE
               |                      |
          TESTDLL2.DLL           TESTDLL2.DLL
               |                      |
          TESTDLL1.DLL           TESTDLL1.DLL
               |                      |
           MFCOxxD.DLL                |
               |                      |
           MFCDxxD.DLL                |
               |                      |
            MFCxxD.DLL            MFCxx.DLL

burada xx sürüm numarasıdır; örneğin, 42 sürüm 4.2'yi temsil eder.

MFCxx.dll genellikle kaynak ve sınıf listesinde son sırada yer alır. MFCxx.dll, tüm standart komut kimlikleri için istem dizeleri de dahil olmak üzere tüm standart MFC kaynaklarını içerir. Listenin sonuna yerleştirmek DLL'lerin ve istemci uygulamasının kendi standart MFC kaynaklarının kopyasına sahip olmamasını, bunun yerine MFCxx.dll dosyasındaki paylaşılan kaynaklara güvenmesini sağlar.

Tüm DLL'lerin kaynaklarını ve sınıf adlarını istemci uygulamasının ad alanıyla birleştirmek, hangi kimlikleri veya adları seçtiğinize dikkat etmenizi gerektiren bir dezavantaja sahiptir.

DLLHUSK örneği, paylaşılan kaynak adı alanını birden çok üst bilgi dosyası kullanarak yönetir.

MFC uzantı DLL'nizin her uygulama için ek veri tutması gerekiyorsa, CDynLinkLibrary'den yeni bir sınıf türetebilir ve içinde DllMainoluşturabilirsiniz. DLL çalıştırılırken, geçerli uygulamanın CDynLinkLibrary nesneleri listesini denetleyerek söz konusu MFC uzantısı DLL'sinin listesini bulabilir.

Ne yapmak istiyorsunuz?

Ne hakkında daha fazla bilgi edinmek istiyorsunuz?

Ayrıca bkz.

Visual Studio'da C/C++ DLL'leri oluşturma