Aracılığıyla paylaş


Uzantı DLL'ler

MFC uzantı DLL'si genellikle mevcut Microsoft Foundation Class Library sınıflarından türetilmiş yeniden kullanılabilir sınıfları uygulayan bir DLL'dir.

MFC uzantı DLL'si, aşağıdaki özelliklere ve gereksinimlere sahiptir:

  • İstemci yürütülebilir, _AFXDLL tanımıyla derlenmiş bir MFC uygulaması olmalıdır.

  • Bir uzantı DLL'si, MFC'ye dinamik olarak bağlanan düzenli bir DLL tarafından da kullanılabilir.

  • Uzantı DLL'ler _AFXEXT tanımlanmış ile derlenmelidir. Bu, _AFXDLL'nin de tanımlanmasını zorunlu kılar ve MFC başlık dosyalarından uygun bildirimlerin çekilmesini sağlar. Ayrıca DLL'i oluştururken AFX_EXT_CLASS öğesinin __declspec(dllexport) olarak tanımlandığından emin olur. Bu, uzantı DLL'nizdeki sınıfları bildirmek için bu makroyu kullanıyorsanız gereklidir.

  • Uzantı DLL'leri CWinApp üzerinden türetilen bir sınıf oluşturmamalı, ancak bu nesneyi sağlamak için istemci uygulamasına (veya DLL'nin) dayalı olmalıdır.

  • Uzantı DLL'leri bununla birlikte bir DllMain işlevi sağlamalı ve bunun üzerinde gerekli her başlatmayı gerçekleştirmelidir.

Uzantı DLL'leri MFC'nin dinamik bağlantı kitaplığı sürümü kullanılarak oluşturulmuştur (aynı zamanda MFC'nin paylaşılan sürümü olarak da bilinir). Yalnızca paylaşılan MFC sürümü ile oluşturulan MFC yürütülebilir dosyaları (uygulamalar veya normal DLL'ler) DLL uzantısını kullanabilir. İstemci uygulaması ve uzantı DLL'si, MFCx0.dll'nin aynı sürümünü kullanmalıdır. DLL uzantısı ile MFC'den yeni özel sınıflar türetebilir ve ardından MFC'nin genişletilmiş bu sürümünü DLL'nizi çağıran uygulamalara sunabilirsiniz.

Uzantı DLL'ler aynı zamanda 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. Bu işlevler MFC'nin paylaşımlı DLL sürümünü kullanırken düzgün biçimde dışarı verildiği için, MFC veya MFC'den türetilmiş nesne işaretleyicilerini bir uygulamayla yüklediği uzantı DLL'leri arasında serbestçe geçirebilirsiniz.

MFC uzantı DLL'si MFC'nin paylaşılan bir sürümünü ilave birkaç husus dışında bir uygulamanın MFC'ye ait paylaşılan DLL sürümünü kullanması ile aynı şekilde kullanır:

  • CWinApp öğesinden türemiş bir nesne içermez. İstemci uygulamasının türetilmiş CWinApp nesnesi ile birlikte çalışmalıdır. Buna göre, istemci uygulamasının ana ileti göndericisi, boşta döngüsü vb. vardır.

  • AfxInitExtensionModule öğesini DllMain işlevinde çağırır. Bu işlevin dönüş değeri kontrol edilmelidir. AfxInitExtensionModule bir sıfır değeri döndürdüyse, DllMain işlevinizden bir 0 değeri döndürün.

  • Uzantı DLL'i CRuntimeClass nesnelerini veya kaynakları uygulamaya dışa aktarmak istiyorsa, başlatma sırasında bir CDynLinkLibrary nesnesi oluşturur.

MFC'nin 4.0 sürümünden önce, önce türde DLL'ye AFXDLL deniyordu. AFXDLL, DLL oluşturulurken tanımlanan önişlemci sembolü olan _AFXDLL'ye tekabül eder.

MFC'nin paylaşılan sürümü için aktarma kitaplıkları MFC DLL'leri için İsimlendirme Kuralları'nda tanımlanan kurala göre adlandırılır. Visual C++ MFC DLL'lerinin önceden oluşturulmuş sürümlerini ve uygulamalarınızla kullanabileceğiniz ve dağıtabileceğiniz bir takım MFC olmayan DLL'ler sağlar. Bunlar Program Files\Microsoft Visual Studio klasörüne yüklenen Redist.txt öğesinde belgelenmiştir.

Bir.def dosyası kullanarak dışa aktarıyorsanız, üstbilgi dosyanızın başına ve sonuna şu kodu ekleyin:

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

Kodun uzantı DLL için doğru olarak derlendiğinden bu dört satır emin olur. Bu dört satırı dışarıda bırakmak DLL'nizin yanlış derlenmesine veya bağlanmasına neden olabilir.

Bir MFC DLL'den veya MFC DLL'ye bir MFC veya MFC türevi nesne işaretçisi geçirmeniz gerekiyorsa, DLL bir uzantı DLL'si olmalıdır. Geçirilen nesneyle ilişkili üye işlevleri nesnenin oluşturulduğu modülde bulunur. Bu işlevler MFC'nin paylaşımlı DLL sürümünü kullanırken düzgün biçimde dışarı verildiği için, MFC veya MFC'den türetilmiş nesne işaretleyicilerini bir uygulamayla yüklediği uzantı DLL'leri arasında serbestçe geçirebilirsiniz.

C++ ad değiştirme ve dışa aktarım sorunları nedeniyle, bir uzantı DLL'den dışa aktarım listesi aynı DLL'nin ve farklı platformlardaki DLL'lerin hata ayıklama ve perakende sürümleri arasında farklılık gösterebilir. Perakende MFCx0.dll yaklaşık 2.000 dışa aktarılan giriş noktası içerir; hata MFCx0D.dll yaklaşık 3.000 dışa aktarılan giriş noktası içerir.

Bellek Yönetimi

Bir istemci uygulamanın adres alanına yüklenmiş MFCx0.dll ve tüm uzantı DLL'leri, aynı uygulamadaymış gibi aynı bellek ayırıcıyı, kaynak yüklemeyi ve diğer MFC genel durumlarını kullanır. Bu çok önemlidir. Çünkü MFC olmayan DLL kitaplıkları ve normal DLL'ler tamamen ters şekilde hareket etmekte ve her DLL'e kendi bellek havuzundan kullandırmaktadır.

Bir uzantı DLL'i bellek ayırırsa, bu hafıza herhangi bir diğer uygulamaya ayrılmış nesneyle serbestçe karışabilir. Ayrıca, MFC'ye dinamik olarak bağlantı sağlayan bir uygulama başarısız olursa, işletim sistemi koruması, DLL'yi paylaşan diğer herhangi bir MFC uygulamasının bütünlüğünü korur.

Benzer şekilde, kaynakların içinden yükleneceği geçerli yürütülebilir dosya gibi diğer global MFC durumları da istemci uygulaması ve MFCx0.dll öğesinin kendisinin yanı sıra tüm MFC uzantı DLL'leri arasında paylaşılır.

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

Kaynakların dışa aktarılması bir kaynak listesi üzerinden yapılır. Her uygulama tek bağlı bir CDynLinkLibrary nesneleri listesi içerir. Bir kaynak ararken kaynakları yükleyen standart MFC uygulamalarının çoğu önce geçerli kaynak modülüne bakar (AfxGetResourceHandle) ve kaynak bulunmazsa istenen kodu yüklemeye çalışarak CDynLinkLibrary nesneleri listesinin üzerinden geçer.

Listenin üzerinden gitmenin biraz daha yavaş olması ve kaynak kimlik aralıklarını yönetmeyi gerektirmesi gibi dezavantajları vardır. Birkaç uzantı DLL dosyasına bağlanan istemci uygulaması herhangi bir DLL tarafından sağlanan kaynağı, DLL örneği işleyicisi belirtmeye gerek kalmadan kullanabilme avantajına sahiptir. AfxFindResourceHandle, kaynak listesini verilen bir eşleşmeyi aramaya sevk etmek için kullanılan bir API'dır. Bir kaynağın adını ve türünü alır ve kaynak işleyicisini ilk bulunduğu yere döndürür (veya NULL).

Listeyi izlemek ve yalnızca belirli bir konumdan kaynak yüklemek istemiyorsanız eski tutamacı kaydedip yenisini ayarlamak için AfxGetResourceHandle ve AfxSetResourceHandle işlevlerini kullanın. İstemci uygulamasına dönmeden önce eski kaynak tanıtıcısını geri yüklediğinizden emin olun. Bu yaklaşımı açıkça bir menü yüklemek için kullanmaya yönelik bir örnek için bkz. MFC örneği DLLHUSK içinde Testdll2 .cpp.

Bir MFC adı verilmiş MFC nesnelerinin dinamik oluşturması benzerdir. MFC nesnesi seri kaldırma mekanizmasının kayıtlı CRuntimeClass nesnelerinin tümüne sahip olması gerekir böylece daha önce depolananlara bağlı olarak gerekli tür C++ nesnelerini dinamik olarak oluşturarak yeniden oluşturabilir.

MFC örneğinin DLLHUSK olması durumunda, liste şöyle görünür:

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

xx sürüm numarası olduğunda; örneğin, 42, 4.2 sürümünü temsil eder.

MFCxx.dll genellikle kaynak ve sınıf listesi üzerinde sonuncudur. MFCxx.dll tüm standart komut kimliklerinin istem dizeleri dahil standart MFC kaynaklarının tümünü içerir. Listenin sonuna yerleştirilmesi DLL'lerin ve istemci uygulamasının standart MFC kaynakları için kendi kopyasına sahip olmadan MFCxx.dll dahilindeki paylaşılan kaynakları kullanmasına izin verir.

Tüm DLL dosyalarının kaynak ve sınıf adlarını istemci uygulamanın ad alanında birleştirirseniz, hangi kimlik veya adları seçtiğinize dikkat etmek gibi bir dezavantaj yaşarsınız.

DLLHUSK örneği paylaşılan kaynak adı alanını çoklu başlık dosyalarını kullanarak yönetir.

MFC uzantısı DLL'nizin her uygulama için fazladan veri koruması gerekiyorsa, CDynLinkLibrary öğesinden yeni bir sınıf türetebilir ve bunu DllMain öğesinde oluşturabilirsiniz. Çalışırken DLL o özel uzantı DLL'si için bir tane bulmak üzere geçerli uygulamanın CDynLinkLibrary nesneleri listesini denetleyebilir.

Ne yapmak istiyorsunuz?

Hangi konu hakkında daha fazla bilgi edinmek istiyorsunuz?

Ayrıca bkz.

Kavramlar

DLL'ler