Bu notu nasıl sen-ebilmek kullanma MFCxx.DLL ve MFCxxD.DLL (burada x mfc sürüm numarasıdır) dinamik bağlantı kitaplıklarını mfc uygulamaları ve uzantısı DLL'ler ile açıklanır. Düzenli DLL hakkında daha fazla bilgi için bkz: Bir dll bir parçası olarak kullanarak mfc.
Bu teknik not üç DLL'leri yönlerini kapsamaktadır. Daha gelişmiş kullanıcılar için son iki vardır:
(Bu normal bir dll denir) olmayan-mfc uygulamaları ile kullanılabilecek mfc kullanılarak bir dll binada ilgileniyorsanız, lütfen Teknik Not 11 ' e bakın.
MFCxx.DLL desteğine genel bakış: terminoloji ve dosyaları
Düzenli dll: normal bir dll mfc sınıfları kullanarak tek başına dll oluşturmak için kullandığınız. "c" arabirim arabirimleri üzerinden App/dll sınırı vardır ve istemci uygulaması, bir mfc uygulaması gerekmez.
Mfc 0'da desteklenen dll desteği sürümüdür. Teknik Not 11 ve mfc Gelişmiş kavram örnek açıklanan dlltrace.
&Notnbsp; Visual c++ sürüm 4.0, usrdll terim kullanılmıyor ve mfc için statik olarak bağlanan normal dll tarafından değiştirilmiştir. Ayrıca dinamik bağlantılar mfc için düzenli bir dll dosyası oluşturabilir.
Mfc 3.0 (ve üstü) ole ve veritabanı sınıfları dahil tüm yeni işlevselliği ile düzenli dll dosyalarını destekler.
afxdll: Bu da mfc kitaplıklarını paylaşılan sürüm olarak adlandırılır. mfc 2.0 içinde eklenen yeni dll desteği budur. mfc Kütüphane (aşağıda açıklanmıştır) DLL dosyaları bir dizi ve bir istemci uygulaması ya da dll gerekli dll dinamik bağlar. Arabirimleri üzerinden uygulama/dll sınırı olan c + +/ mfc sınıf arabirimleri. İstemci uygulaması bir mfc uygulaması olması gerekir. Bu tüm mfc 3.0 işlevselliği destekler (excption: UNICODE veritabanı sınıflarını desteklenmez).
&Notnbsp; Visual c++ 4.0 sürümü olarak, bu tür bir dll için "Uzantısı dll." denir
Bu notu içeren dll mfc ayarlamak, tüm için başvuruda bulunmak için MFCxx.DLL kullanır:
&Notnbsp; MFCSxx [u] [d].LIB kitaplık olarak kullanılan mfc ile birlikte paylaşılan DLL'lerin. Bu kitaplıkları statik olarak uygulama veya dll bağlanması gerekir kod içerir.
Buna karşılık gelen bir uygulama bağlantıları alma kitaplıkları:
Bir "mfc uzantısı dll" MFCxx.DLL inşa edilmiş bir dll (veya diğer mfc paylaşılan DLL'lerin). Burada mfc bileşen mimarisi kicks. Yararlı bir sınıf bir mfc sınıfından türetilir ya da başka bir mfc benzeri araç seti oluşturmak, bir dll yerleştirebilirsiniz. dll olarak MFCxx.DLL, kullandığı son istemci uygulaması yok. Bu yeniden yaprak sınıfları, yeniden kullanılabilir temel sınıflar ve yeniden kullanılabilir belge görüntüle dersleri verir.
&Notnbsp; mfc/ole, veritabanı veya ağ sınıfları sırasıyla uygulamanızın kullandığı sürece MFCOxx [u] d, MFCDxx [u] d veya d MFCNxx [u] Debug kütüphaneleri ile bağlamak gerekli değil.
Artıları ve eksileri
Neden mfc paylaşılan sürümünü kullanmalısınız?
Neden mfc paylaşılan sürümünü kullanmalısınız değil:
Bir mfc uzantı DLL'si, sınıflar ve mfc sınıflar işlevselliğini güzelleştirmek için yazılmış işlevleri içeren bir dll'dir. ole ve veritabanı hata ayıklama desteği dll dosyaları (MFCOxxD.DLL ve MFCDxxD.DLL), onlar MFCxxD.DLL kullandıkları mfc uzantısı dll örnekleri verilmiştir. Bir uygulama, birkaç ek hususlar ile kullandığı aynı şekilde paylaşılan mfc dll mfc uzantısı dll kullanır:
Bu noktalar aşağıda ayrıntılı olarak açıklanmıştır. mfc Gelişmiş kavram örnek için Ayrıca başvuru beri bunu göstermektedir dllhusk
İstemci uygulaması hem de herhangi bir uzantısı dll MFCxx.DLL aynı sürümünü kullanmanız gerekir. mfc dll kuralları izleyin ve her bir hata ayıklama sağlamak gerekir ve perakende (/ release), uzantı dll sürümü. Bu istemci programların uygulamalarını hem hata ayıklama hem de perakende sürümlerini kurmak ve onlara uygun hata ayıklama ya da perakende sürümü tüm DLL'leri ile bağlantı verir.
&Notnbsp; c++ adı bozma ve ihracat sorunu nedeniyle bir uzantı DLL'si ihracat listeden farklı platformlar için aynı dll hata ayıklama hem de perakende sürümlerini ve DLL'ler farklı olabilir. Perakende MFCxx.DLL yaklaşık 2000 giriş noktaları dışa; debug MFCxxD.DLL yaklaşık 3000 giriş noktaları dışa.
Hızlı Not bellek yönetimi
Bu teknik notu sonuna "bellek yönetimi" başlıklı bölümü MFCxx.DLL uygulanması ile mfc paylaşılan sürümünü açıklar. Sadece bir uzantı dll uygulamak için bilmeniz gereken bilgiler burada açıklanan.
Aynı uygulamada sanki MFCxx.DLL ve tüm uzantı DLL bir istemci uygulamanın adres alanına yüklenen aynı bellek ayırıcı, kaynak yükleme ve diğer mfc "küresel" devletler kullanacaktır. mfc dll Kitaplığı ve düzenli dll mfc için statik olarak bağlantı tam tersi yapmak ve her dll üzerinden kendi bellek havuzu tahsis bu önemlidir, çünkü.
Bir uzantı DLL'si bellek ayırır, belleğin özgürce diğer uygulama tarafından ayrılmış nesneleri Intermix. İşletim sisteminin korunması paylaşılan mfc kitaplıklarını kullanan bir uygulama çöker, Ayrıca, dll paylaşım başka bir mfc uygulama bütünlüğünü korumak.
Benzer şekilde, kaynaklardan yüklemek için geçerli çalıştırılabilir dosya gibi "küresel" diğer mfc devletler de istemci uygulaması ve bütün mfc uzantısı DLL'ler gibi arasında MFCxx.DLL kendisi paylaşılır.
Bir uzantı DLL'si oluşturma
AppWizard bir mfc uzantısı dll proje oluşturmak için kullanabileceğiniz ve uygun derleyici ve ilintileyici ayarlarını otomatik olarak oluşturur. O da, değiştirebileceğiniz bir DllMain işlevi oluşturmak.
Varolan bir projeyi mfc uzantısı dll dönüştürüyorsanız, mfc paylaşılan sürümünü kullanan bir uygulama oluşturmak için standart kurallar ile başlayın, sonra şunları yapın:
Üstbilgisini dosyalarınızı değiştirme
Uzantı dll genellikle bu işlevler kullanabileceğiniz bir veya daha fazla uygulamaya bazı ortak işlevselliği vermek hedefidir. Bu sınıflar ve istemci uygulamalarınız için kullanılan genel işlevlerini dışa aktarma için kaynar.
Bunun için her üye işlevleri olarak aldığınızda veya uygun şekilde işaretlenmiş sigorta gerekir. Bu özel tanımlamalar gerektirir: __declspec(dllexport) ve __declspec(dllimport). Dersleriniz istemci uygulamaları tarafından kullanıldığında, __declspec(dllimport)ilan etmelerini istiyorum. Uzantı DLL'si kendisi inşa ediliyor, __declspec(dllexport)bildirilmelidir. Böylece istemci programları onlara yük zaman bağlamak ayrıca işlevleri aslında, verilmelidir.
Tüm sınıf vermek için sınıf tanımında afx_ext_class kullanın. _afxdll ve _afxext tanımlanan, ama _afxext değil tanımlandığında __declspec(dllimport) tanımlanan bu makro çerçeve tarafından __declspec(dllexport) tanımlanır. _afxext yukarıda açıklandığı gibi yalnızca sizin uzantı DLL'si oluşturulurken tanımlanır. Örneğin:
afx_ext_class CExampleExport sınıfı: Genel CObject
{... sınıf tanımı...}
Tüm sınıf verme değil
Bazen sınıf sadece bireysel gerekli üyeleri vermek isteyebilirsiniz. Örneğin, bir CDialogveriyorsanız-türetilmiş sınıf, sadece kurucu ve DoModal çağrı vermeniz gerekebilir. Bu üyeler dll kullanarak dışa aktarabilirsiniz.def dosya kullanabilirsiniz, ancak sen de afx_ext_class çok aynı şekilde vermeniz gerekir tek tek üyeleri.
Örneğin:
cExampleDialog sı&nıfı: Genel CDialog
{
public:
nbsp; afx_ext_class CExampleDialog();
afx_ext_class int DoModal();
/ / dinlenme sınıf tanımı
.
.
.
}
Bunu yaptığınızda, gerçeği artık sınıfının tüm üyelerine vereceğiniz ek bir sorun haline çalışabilir. Bir şekilde bu mfc makrolar iş sorunudur. MFC'ın Yardımcısı makroların bazıları gerçekten beyan veya veri üyeleri tanımlayın. Bu nedenle, bu veri üyeleri de dll dosyasından verilmesi gerekir.
Örneğin, DECLARE_DYNAMIC makro şöyle bir uzantı DLL'si oluşturulurken tanımlanır:
# define DECLARE_DY&NAMIC(class_name) \
Korumalı: \
nbsp; statik CRuntimeClass * pascal _GetBaseClass(); \
public: \
statik afx_data CRuntimeClass sınıf ## sınıf; \
Sanal CRuntimeClass * const GetRuntimeClass(); \
"Statik afx_data" başlayan satırı, bir duruk nesne sınıfının içinde bildirmek. Bu sınıf doğru vermek ve çalışma zamanı bilgileri bir istemcisinden erişmek için.exe, bu statik nesne vermeniz gerekir. Duruk nesne afx_datadeğiştirici ile bildirildiğinden, sadece dll oluştururken __declspec(dllexport) olmak afx_data tanımlamak ve istemcinizin yürütülebilir oluştururken __declspec(dllimport) tanımlamak gerekir.
Yukarıda bahsedildiği gibi afx_ext_class zaten bu şekilde tanımlanır. Böylece sadece afx_ext_class aynı olması, sınıf tanımı afx_data yeniden tanımlamak gerekir.
Örneğin:
nbsp; #undef afx_data
# define afx_data afx_ext_class
CExampleView sınıfı: Genel CView
{
DECLARE_DY&NAMIC()
/ /... sınıf tanımı...
};
#undef afx_data
# define afx_data
Mfc afx_data sembolü bu tekniği böyle senaryolar için çalışması makroları, tanımladığı veri öğeleri her zaman kullanır. Örneğin o-ecek iş için declare_message_map.
&Notnbsp; Seçili üyeleri sınıfı yerine, tüm sınıf veriyorsanız, statik veri üyeleri otomatik olarak verilir.
Otomatik olarak CArchive çıkarma işleci için DECLARE_SERIAL ve IMPLEMENT_SERIAL makroları kullanma dersleri vermek için aynı tekniği kullanabilirsiniz. Arşiv operatör sınıfı bildirimleri tarama tarafından İhracat (yer.h dosyası) aşağıdaki kodu ile:
#undef AFX_API
# define AFX_API afx_ext_class
lt; burada sınıf bildirimleri >
#undef AFX_API
# define AFX_API
_afxext sınırlamaları
Çok katmanlı uzantısı DLL yoktur sürece, uzantısı dll _afxext pre-processor simgesini kullanabilirsiniz. Uzatma seslenmek ya da kendi uzantısı DLL'ler, hangi sonra mfc sınıftan türemesine, sınıflardan türetmek DLL varsa belirsizlik önlemek için kendi Önişlemci sembolü kullanmanız gerekir.
Eğer o bir dll dosyasından alınmış olması bir dll ve __declspec(dllimport) verilecek ise Win32'de açıkça herhangi bir veri __declspec(dllexport) bildirmelisiniz ki sorunudur. _afxexttanımladığınızda, mfc başlıkları afx_ext_class doğru biçimde tanımlandığından emin olun.
Birden çok katmanı varsa, bir uzantı DLL'si yeni sınıflar verme yanı sıra başka bir uzantı DLL'SİNDEN diğer sınıfları içe afx_ext_class gibi bir simge yeterli değildir. Bu sorunu ile başa çıkmak için dll dosyasını kullanarak karşı dll kendisini oluşturmakta olduğunuz gösterir bir özel pre-processor sembolü kullanın. Örneğin, iki uzantı DLL, a.dll ve b.dll düşünün. Her sırasıyla h. ve b.h, bazı dersleri vermek. b.dll a.dll sınıflardan kullanır. Başlık dosyaları bu şöyle:
/ / H.
#ifdef A_IMPL
# define class_decl_a __declspec(dllexport)
# başka
# define class_decl_a __declspec(dllimport)
endif
class_decl_a CExampleA sınıfı: Genel CObject
{... sınıf tanımı...};
/ / B.H
#ifdef B_IMPL
# define class_decl_b __declspec(dllexport)
# başka
# define class_decl_b __declspec(dllimport)
endif
class_decl_b CExampleB sınıfı: Genel CExampleA
{... sınıf tanımı..}
A.dll oluşturulduğunda, d A_IMPL ile inşa edilmiştir ve b.dll oluşturulduğunda, d B_IMPLile inşa edilmiştir. Her dll için ayrı sembolleri kullanarak, CExampleB verilir ve CExampleA b.dll bina alınır. CExampleA a.dll oluştururken ihraç ve ithal b.dll (veya başka bir istemci) kullanıldığında.
Bu tür bir katman, yerleşik afx_ext_class ve _afxext pre-processor Semboller kullanırken yapılamaz. Yukarıda açıklanan teknik bir şekilde değil aksine mekanizması mfc kendisini kendi ole, veritabanı ve ağ uzantı DLL'leri oluştururken kullandığı bu sorunu çözer.
Tüm sınıf verme değil
Tekrar bir bütün sınıf verildiğinde değil özel dikkat gerekir. mfc makrolarla oluşturulan gerekli veri öğelerini doğru şekilde verilir sağlamak zorunda. Bu, belirli bir sınıf makro afx_data gelenlerinden tarafından yapılabilir. Bu tüm sınıf vereceğiniz değil her zaman yapılmalıdır.
Örneğin:
/ / H.
#ifdef A_IMPL
nbsp; # define class_decl_a _declspec(dllexport)
# başka
# define class_decl_a _declspec(dllimport)
endif
#undef afx_data
# define afx_data class_decl_a
CExampleA sınıfı: Genel CObject
{
DECLARE_DY&NAMIC()
class_decl_a int SomeFunction();
//Class tanımı.
.
.
};
#undef afx_data
# define afx_data
DllMain
Ana kaynak dosyanız için uzantı DLL'si yerleştirmelisiniz tam kodu aşağıdadır. Standart yükleme sonra gelmelidir. Başlangıç dosyaları için bir uzantı dll oluşturmak için AppWizard kullandığınızda, bir DllMain için sa?lady?y olduğunu unutmayın.
# include "afxdllx.h"
statik AFX_EXTE&NSION_MODULE extensionDLL;
extern "c" int APIENTRY DllMain (HINSTANCE HINSTANCE, dword dwReason, LPVOID)
{
nbsp; Eğer (dwReason == dll_process_attach)
{
/ / Uzantı dll bir kerelik başlatma Eğer (!AfxInitExtensionModule)
extensionDLL, HINSTANCE))
return 0;
/ / todo: diğer başlatma görevlerini gerçekleştirme
}
else if (dwReason == dll_process_detach)
{
/ / Uzantı DLL'si her işlem sonlandırma
AfxTermExtensionModule(extensionDLL);
/ / todo: diğer temizleme görevleri gerçekleştirmek
}
return 1; / / ok
}
CDynLinkLibrary nesne oluşturulduğunda AfxInitExtensionModule çağrısı modüller runtime-sınıflar (CRuntimeClass yapıları) yanı sıra daha sonra kullanmak için nesne fabrikalar (COleObjectFactory nesneleri) yakalar. Zaman her işlem (Bu işlem çıktığında ya da dll FreeLibrary arama sonucu kaldırıldığında olur) ucun AfxTermExtensionModule (isteğe bağlı) çağrısı mfc temizleme için uzantı DLL'si sağlar uzantısı dll. Çoğu uzantı dll dinamik olarak yüklenmez beri (genellikle, onlar ithalat arşivlerine bağlı), AfxTermExtensionModule çağrısı genellikle gerekli değildir.
Uygulama yükler ve uza&ntı dll dinamik olarak boşaltır, AfxTermExtensionModule olarak gösterilen above.nbsp çağırdığınızdan emin olun; Ayrıca birden çok iş parçacığı uygulama kullanıyorsa, AfxLoadLibrary ve AfxFreeLibrary (Win32 işlevlerini yerine LoadLibrary ve FreeLibrary) kullandığınızdan emin olun. AfxLoadLibrary ve AfxFreeLibrary kullanarak uzantısı dll yüklendi ve kaldırıldı yürütür başlatma ve kapatma kodu genel mfc durumu bozuk değil sigortalanır.
Üstbilgisini dosyanın afxdllx.H özel defintions uzantılı DLL'ler, AFX_EXTENSION_MODULE ve CDynLinkLibrary tanımı gibi kullanılan yapıları içerir.
Görüldüğü gibi küresel extensionDLL bildirilmesi gerekir. 16-Bit sürümünü mfc, bellek ve MFCxx.DLL tamamen sizin DllMain denir zaman başlatıldı çünkü bu süre zarfında mfc işlevleri çağırmak.
Paylaşım kaynakları ve sınıfları
Basit mfc uzantısı dll sadece birkaç düşük bant genişlikli işlevleri istemci uygulaması ve hiçbir şey daha fazla verme. Daha fazla kullanıcı arabirimi yoğun DLL'leri kaynakları ve c++ sınıfları istemci uygulamasına vermek isteyebilirsiniz.
Kaynak verme bir kaynak listesi üzerinden yapılır. Her uygulamada CDynLinkLibrary nesneleri tek başına bağlantılı bir listesidir. Standart mfc uygulamaları yükleme kaynakları geçerli kaynak modül (AfxGetResourceHandle) ilk bakmak çoğu kaynak ararken ve bulunamadı bir yürüyüş, istenen kaynak yüklenmeye çalışılıyor CDynLinkLibrary nesneleri listesi.
Dinamik bir c++ sınıf adı verilen c++ nesneleri benzer oluşturulmasıdır. mfc nesnesi serisini kaldırma mekanizması bu dinamik olarak ne daha önce depolanan Tarih alarak gerekli türü c++ nesnesi oluşturarak yeniden böylece kayıtlı CRuntimeClass nesnelerin tümü olması gerekir.
Eğer DECLARE_SERIAL, uzantısı dll sınıfları kullanmak için istemci uygulaması, istemci uygulaması için görünür olması için sınıfları vermeniz gerekir. Bu da CDynLinkLibrary liste yürüyerek yapılır.
Mfc Gelişmiş kavram örnek ise dllhusk, listesine bakar gibi bir şey
baş - > DLLHUSK.exe - veya - dllhusk.EXE
| |
TESTDLL2.DLL TESTDLL2.DLL
| |
TESTDLL1.DLL TESTDLL1.DLL
| |
MFCO42D.DLL |
| |
MFCD42D.DLL |
| |
MFC42D.DLL MFC42.DLL
MFCxx.DLL genellikle son sınıf listesi ve kaynak. MFCxx.DLL tüm standart komut kimliklerini için komut isteminde dizeleri gibi standart mfc kaynakları içerir. Liste kuyruğu yerleştirerek sağlayan DLL'leri ve sahip olmadığı için istemci uygulamanın kendisi bir standart mfc kaynakları, MFCxx.DLL paylaşılan kaynakları yerine güvenmek üzere ama kendi kopyasını.
Kaynaklar ve tüm DLL'leri sınıf adlarını istemci uygulamanın adı alanına birleştirme ne kimlikleri dikkatli olmak zorunda dezavantajı ya da seçtiğiniz adları vardır. Kaynaklarınız ya da bir CDynLinkLibrary nesnesi istemci uygulamaya aktararak değil tabii bu özelliği devre dışı bırakabilirsiniz. dllhusk örnek birden fazla başlık dosyalarını kullanarak paylaşılan kaynak adı alanı yönetir. Teknik Not 35 bkz: paylaşılan kaynak dosyalarını kullanma hakkında daha fazla ipucu için.
Dll başlatılıyor
Yukarıda belirtildiği gibi genellikle dersleri ve kaynakları istemci uygulamasına dışa aktarmak için bir CDynLinkLibrary nesnesi oluşturmak isteyeceksiniz. Dll dosyasını başlatmak için verilen giriş noktası sağlamanız gerekir. Minimal bu bağımsız değişken alan ve hiçbir şey döndüren void bir rutin olduğunu, ama o-ebilmek var olmak gibi bir şey.
Bu yaklaşımı kullanırsanız, her istemci uygulaması dll kullanmak istediği bu başlatma yordamı çağırmalısınız. Siz de bu CDynLinkLibrary nesne içinde senin DllMain sadece AfxInitExtensionModule çağrıldıktan sonra tahsis.
Başlatma yordamı geçerli uygulama yığın, senin uzantısı dll bilgi kadar kablolu bir CDynLinkLibrary nesnesi oluşturmanız gerekir. Bu aşağıdaki ile yapılabilir:
extern "c" extern void WI&NAPI InitXxxDLL()
{
nbsp; Yeni CDynLinkLibrary(extensionDLL);
}
Rutin adı, InitXxxDLL bu örnekte, istediğiniz herhangi bir şey olabilir. Bunun gerekli değildir extern “C” , yani geçici ihracat listesi bakımını daha kolay yapıyor ama.
&Notnbsp; Senin uzantısı dll düzenli bir dll dosyasından kullanırsanız, bu başlatma işlevi vermelisiniz. Herhangi bir uzantısı dll sınıfları veya kaynakları kullanmadan önce normal dll dosyasından bu işlevi çağrılmalıdır.
Girişleri verme
Sınıfları dışa aktarmak için basit bir şekilde __declspec(dllimport) ve __declspec(dllexport) her sınıf ve genel işlevi, dışa aktarmak istediğiniz kullanmaktır. Bu çok kolaylaştırır, ama beri hangi fonksiyonlar verilebilir daha az denetim sahibi ve sıra ile işlevleri verilemiyor (aşağıda açıklanmıştır) her bir giriş noktası adlandırma daha az etkilidir. Hem TESTDLL1 hem de TESTDLL2 kendi girişlerini vermek için kullandığı yöntem budur.
Her giriş adlandırarak her girişi el vermek daha verimli bir yöntem (ve MFCxx.DLL tarafından kullanılan yöntem) olduğunu.def dosyası. Çünkü bizim dll (başka bir deyişle, her şey) Seçmeli ihracat dışa aktarıyorsanız, biz hangi belirli arabirimleri vermek istediğimiz karar vermeniz gerekir. Karıştırılmış adları için bağlayıcı girişler şeklinde belirtmelisiniz zor olduğu için bu.def dosyası. Gerçekten bunun için sembolik bir bağlantı olması gerekir sürece herhangi bir c++ sınıfları vermeyin.
Eğer sen-si olmak güvenilir verme c++ sınıfları ile bir.def, sen-ebilmek istemek-e bu liste otomatik olarak oluşturmak için bir araç geliştirmek önce dosya. Bu yapılabilir bir iki sahne bağlama işlemini kullanma. dll hemen hiçbir ihracat ile bağlantı ve bağlayıcı oluşturmak izin bir.Eşleştirme dosyası. .Eşleştirme dosyası, bazı munging ile o, ihracat girdileri oluşturmak için kullanılabilecek şekilde verilmesi işlevler listesini oluşturmak için kullanılabilir.def dosyası. Her ne kadar (tamamen otomatik değildir ve her bir kez içinde a süre ayarlama bazı el gerektirir) MFCxx.DLL ve ole ve veritabanı uzantısı DLL'ler, birkaç bin sayısı, ihracat listesi böyle bir süreç ile oluşturuldu.
CWinApp vs. CDynLinkLibrary
Bir mfc uzantısı dll CWinAppyok-nesne kendi; elde edilen Bunun yerine CWinAppile çalışması gerektiğini-nesnesi istemci uygulamanın türetilmiş. İstemci uygulaması ana mesajı pompa, boşta döngü vesaire sahibi yani.
Mfc uzantısı dll her uygulama için ek verileri korumak gerekiyorsa, CDynLinkLibrary yeni bir sınıf türetmek ve rutin tanımlamak yukarıda InitXxxDLL içinde oluşturun. dll-ebilmek kontrol bu özel uzantı dll bulmak için CDynLinkLibrary nesneleri listesi geçerli uygulama çalıştırırken,.
Kaynak dll uygulamanız kullanma
Yukarıda belirtildiği gibi varsayılan kaynak yükü seyir için ilk exe ya da dll istenen kaynak olan CDynLinkLibrary nesnelerin listesini gösterecektir. Tüm mfc API'leri yanı sıra tüm dahili kod bulunduğu olursa olsun herhangi bir kaynak bulmak üzere kaynak listesini yürümeye AfxFindResourceHandle kullanır.
Yalnızca belirli bir yerden kaynak yüklemek isterseniz, API'leri kullanan eski kolu kaydetmek ve yeni tanıtıcı ayarlamak için AfxGetResourceHandle ve AfxSetResourceHandle . Eski Kaynak tanıtıcısı istemci uygulamasına döndürür önce geri emin olun. Örnek TESTDLL2, açıkça bir menü yüklemek için bu yaklaşım kullanır.
Liste yürüyüş biraz daha yavaştır ve kaynak kimlik aralığı yönetimi gerektirir dezavantajları vardır. Birkaç uzantı DLL dosyalarına bağlanan istemci uygulaması dll tarafından sağlanan kaynak dll örneği tutamacı eklemenize gerek kalmadan kullanabileceğiniz avantajına sahiptir. AfxFindResourceHandle kaynak listesini yürüyüş için verilen bir eşleşme aramak için kullanılan bir API'dır. Bir kaynak türü ve adı alır ve ilk bulunduğu kaynak tanıtıcısı (veya null) döndürür.
Başvuru koşulları
Mfc paylaşılan sürümünü kullanan bir uygulama birkaç basit kurallara uymalıdır:
Geliştirme ortamı ile bina
İç makefile standart varsayılan bir çoğunu ile kullanıyorsanız, dll sürümünü kurmak için proje kolayca değiştirebilirsiniz.
Aşağıdaki adımı düzgün işleyen bir mfc uygulaması ile nafxcwd bağlı olduğunuz varsayılmaktadır.LIB (debug için) ve nafxcw.LIB (perakende için) ve mfc kitaplık paylaşılan sürümünü kullanmak için dönüştürmek istiyorsanız. Visual c++ ortamında çalıştırıyorsanız ve bir dahili proje dosyası.
Bina ile nmake
Visual C++'ın dış makefile özelliğini kullanarak ya da nmake doğrudan kullanıyorsanız, derleyici ve ilintileyici seçeneklerini desteklemek için makefile düzenlemek gerekecek
Gerekli derleyici bayrakları:
/ D_AFXDLL /MD
/ D_AFXDLL
Tanımlanan bu sembol standart mfc başlıklara gerek:
/MD
Uygulama c Çalışma Zamanı Kitaplığı dll sürümünü kullanmanız gerekir
Tüm diğer derleyici bayraklar mfc varsayılan değerleri (örneğin, _debug için hata ayıklama) izleyin.
Kitaplıklar bağlayıcı listesini düzenleyin. Değişim nafxcwd.MFCxxD.LIB için LIB ve nafxcw değiştirin.LIB MFCxx.LIB için. MFCOxx[U]D.LIB, MFCDxx[U]D.LIB ve MFCNxx[U]D.LIB uygun olarak (mfc/ole, veritabanı ya da ağ sınıfları kullanmak için gerekli) ekleyin. LIBC değiştirin.msvcrt ile LIB.LIB. Diğer bir mfc kitaplık ile MFCxxD.LIB önce yerleştirilir önemli olduğu gibi hiçbir c çalışma zamanı kitaplıkları.
İsteğe bağlı olarak, hem perakende /d_afxdll ekleyin ve kaynak derleyici seçenekleri (aslında /r kaynaklarla derler bir) hata ayıklama. Bu, nihai çalıştırılabilir mfc DLLs içinde mevcut olan kaynakları paylaşarak küçültür.
Bu değişiklikler yapıldıktan sonra tam bir yeniden gereklidir.
Örnekleri oluşturma
Mfc örnek programların çoğu Visual c++ veya bir paylaşılan nmake uyumlu MAKEFILE komut satırından inşa edilecek.
Bu örnekler MFCxx.DLL kullanmak için herhangi bir dönüştürme için yükleyebilirsiniz.mak Visual c++ dosyası ve yukarıda açıklandığı gibi proje seçeneklerini ayarlayın. Belirleyebileceğiniz nmake inşa kullanıyorsanız, "afxdll = 1" paylaşılan mfc kitaplıklarını kullanarak örnek komut satırı ve bu nmake inşa edecek.
Mfc Gelişmiş kavram örnek dllhusk mfc dll sürümü ile inşa edilmiştir. Bu örnek sadece MFCxx.DLL ile bağlantılı bir uygulamalarının nasıl oluşturulacağını göstermektedir, ancak Ayrıca mfc dll paketleme seçeneğinin mfc uzantısı dll daha sonra bu teknik notta açıklandığı gibi diğer özellikler göstermektedir.
Ambalaj notları
Perakende sürümü dll (MFCxx [u].dll) serbestçe dağıtılabilir vardır. Dll hata ayıklama sürümünü serbestçe dağıtılabilir değildir ve yalnızca uygulamanızın geliştirilmesi sırasında kullanılmalıdır.
Hata ayıklama dll ile hata ayıklama bilgileri sağlanmaktadır. Visual c++ hata ayıklayıcısı kullanarak, dll yanı sıra uygulamanızın çalışmasını izleyebilirsiniz. Yayın dll (MFCxx [u].dll) hata ayıklama bilgileri içermez.
Özelleştirmek veya DLL dosyalarını yeniden, sonra sen onları bir şey diğer--dan "MFCxx" mfc kaynak dosyası mfcdll çağırmalıdır.mak oluşturma seçenekleri'ni tanımlar ve dll dosyasını yeniden adlandırma mantığı içerir. Bu kural, mfc/ole, veritabanı ve ağ mfcole tarafından inşa dll dosyaları için de geçerlidir.MAK, MFCDB.mak ve mfcnet.mak, sırasıyla. Dosyaları yeniden adlandırma gerekli, çünkü bu DLL'lerin olabilecek birçok mfc uygulamaları tarafından paylaşılır. mfc DLL'leri özel sürümü olan bu sistemde yüklü Değiştir paylaşılan mfc DLL'ler kullanarak başka bir mfc uygulaması kırılabilir.
Mfc dll dosyalarını yeniden önerilmez.
Aşağıdaki bölümde, mfc dll (MFCxx.DLL ve MFCxxD.DLL) nasıl uygulanır açıklar. Burada ayrıntıları da değildir anlamak tüm sen yapmak istiyorsanız mfc dll ile uygulamanızı kullanmak önemlidir. Burada ayrıntıları nasıl dll mfc uzantı yazmak anlamak için gerekli değildir, ancak bu uygulama anlayışı kendi dll yazmanıza yardımcı olabilir.
Uygulama genel bakış
Mfc dll mfc uzantısı dll özel bir durum yukarıda açıklandığı gibi gerçekten. İhracat için sınıflar çok sayıda çok sayıda bulunmaktadır. O daha özel daha düzenli bir uzantı dll mfc dll yaptığımız birkaç ek şeyler yapmak vardır.
Win32 işin çoğunu yok
Mfc 16 bitlik sürümü özel teknikler de-app veri yığın kesiminin, 80 x 86 assembly kodu, işlem başına özel içerikler ve diğer teknikleri tarafından oluşturulan özel kesimler de dahil olmak üzere çok sayıda gerekli. Win32 doğrudan olduğu çoğu zaman istediğim bir dll, işlem başına verileri destekler. Çoğunlukla MFCxx.DLL sadece nafxcw olduğunu.Bir dll içinde paketlenmiş LIB. mfc kaynak koda bakarsanız, çünkü yapılması gereken çok az sayıda özel durumlarda çok az #ifdef _afxdll, bulabilirsiniz. Orada özellikle Win32 Windows 3.1 (aksi takdirde Win32s da bilinir) ile başa çıkmak için olan özel durumlar. mfc dll iş parçacığı yerel depolama (tls) işlemi yerel verileri elde etmek için Win32 API'larının çok kullanmalısınız doğrudan Win32s değil destek işlem başına dll verileri yok.
Kütüphane kaynakları, ek dosyalar üzerindeki etkisi
_afxdll sürüm normal mfc sınıf Kütüphane kaynakları ve başlıkları etkisi nispeten küçük. Bir özel sürüm dosya (afxv_dll.h) gibi bir ek üstbilgi dosyası (afxdll_.h) tarafından ana AFXWIN dahil.H başlığı. ««««afxdll_.H başlık CDynLinkLibrary sınıfı ve _afxdll uygulamaları ve mfc uzantısı dll diğer uygulama ayrıntılarını içerir. ««««afxdllx.H üstbilgi mfc uzantısı dll (detaylar için bakınız yukarıda) oluşturmak için sağlanan.
Mfc src mfc Kütüphane düzenli kaynaklarına ek bazı koşullu kod altında _afxdll #ifdef var. Bir ek kaynak dosya (DLLINIT.cpp) ilave dll başlatma kodu ve diğer yapıştırıcı mfc paylaşılan sürümü içerir.
Mfc paylaşılan sürümünü kurmak için ek dosyalar sağlanmıştır. (dll oluşturmak için Ayrıntılar için aşağıya bakın.)
Mfc dll oluşturma
Mfc dll kasten zor, Peki sence iki kez yeniden (veya üç kere) önce yapıyor. Eğer olası ambalaj sorunları ve aşağıda açıklanan dağıtım kısıtlamaları ve hala gerçekten anlamak mfc dll dosyasını yeniden oluşturmanız gerekir, sen.
««««mfcdll.mak dosya hata ayıklama dll CodeView bilgi ile inşa edecek:
Nmake /f mfcdll.mak debug = 1 LIBNAME = mymfc
««««mfcdll.mak dosya sürümü dll CodeView bilgisi olmadan inşa edecek:
Nmake /f mfcdll.mak debug 0 LIBNAME = mymfc =
(benzer bir şekilde, mfcole kullanın.MAK, MFCDB.mak ve mfcnet.mak MFCOxxD.DLL, MFCDxxD.DLL ve MFCNxxD.DLL--mfc/ole, veritabanı ve ağ sınıfları içeren DLL oluşturmak için)
Bu mfc dll mfc src dizinindeki standart MFCxx.DLL ve MFCxxD.DLL adlarıyla özel bir sürümünü inşa edecek. Yolda yeni DLL'leri kullanmayı uygun bir yere kopyalamanız gerekir. ««««mfcdll.mak makefile da yeniden alma kütüphaneleri (MFCxx.LIB ve MFCxxD.LIB) ve standart mfc LIB dizinine yerleştirin. Bu yüzden önceden oluşturulmuş MFCxx.LIB ve MFCxxD.LIB kitaplıkları yerini alacak lütfen dikkatli olun.
Mfc dll Kitaplığı değiştirilmiş bir sürümünü dağıtmak isterseniz, mfcdll dll adını değiştirmek emin olun.mak makefile ve iki.def dosyaları. Makefile mfcdll bakın.Daha fazla bilgi için mak.
İstediğiniz kitaplığını değiştirme ve yeniden dağıtan bir perakende (/ release) eğer sadece o MFCxx.DLL dışında herhangi bir öğeye yeniden değiştirilmiş kitaplığınızın. Önceden ya da özel yapılı debug dll ya da hata ayıklama sürümünü dağıtamaz.
Bu dağıtım kısıtlamaları, standart olmayan bir yayılması önlemek için öncelikle vardır ve potansiyel virüs içeren dll. ideal, dll dosyalarını yeniden gerekmez ve Visual c++ ürünle birlikte verilen önceden oluşturulmuş MFCxx.DLL ile uygulama yeniden dağıtma, kendiniz ve kullanıcılar için sorun bir sürü kalmazsınız.
Bellek yönetimi
MFCxx.DLL kullanan bir uygulama MSVCRTxx.DLL, paylaşılan c Çalışma Zamanı dll tarafından sağlanan ortak bir bellek ayırıcı kullanır. Hem uygulama, herhangi bir uzantısı DLL'ler, hem de mfc DLL'leri kendilerini, bu paylaşılan bellek ayırıcı kullanın. Bellek ayırma için paylaşılan dll, mfc DLL'ler kullanarak hangi uygulama veya tersi daha sonra serbest bellek ayırabilirsiniz. Hem uygulama hem de dll aynı ayırıcı kullanmanız gerekir çünkü size c++ genel operatör yeni veya işleç silmegeçersiz kılmak değil. c-çalışma bellek ayırma yordamları (malloc, realloc, ücretsiz, vb.. gibi) geri kalanı için aynı kurallar geçerlidir.
Sıra sayılarını ve sınıf __declspec(dllexport) ve dll adlandırma
Biz kullanmayın class c++ derleyici __declspec(dllexport) işlevi. Bunun yerine, ihracat listesi sınıf Kütüphane kaynakları ile (MFCxx.DEF ve MFCxxD.DEF) bulunur. Giriş noktalarını (işlevleri ve veri) select bu dizi verildi. mfc özel uygulama işlevleri veya sınıflar gibi diğer simgeler aktarılmaz tüm ihracat tarafından sıra yerleşik ya da Yerlesik adı tablosunda dize adı olmadan yapılır .
Kullanarak class __declspec(dllexport) küçük dll oluşturmak için bir alternatif olabilir, ama mfc gibi büyük bir dll durumunda, verimlilik ve kapasite mekanizması verme varsayılan olan sınırları .
Tüm bu anlamı nedir biz işlevselliği, yalnızca çok yürütme tehlikeye veya yükleme hızı yaklaşık 800 KB MFCxx.DLL sürümdeki büyük miktarda paketleyebilirsiniz. MFCxx.DLL olurdu 100 k büyük bu tekniği değil be kullanılmış.Bu da sonunda ek giriş noktaları eklemek sağlar.def dosyası tarafından sıra verme hızı ve boyutu verimliliği ödün vermeden basit sürüm oluşturma izin vermek. Ana sürüm değişiklikleri mfc sınıf kitaplığı kitaplık adı değişecek. Yani MFC30.dll mfc class library 3.0 sürümünü içeren yeniden dağıtılabilir dll'dir. Bu dll, yükseltmesi diyorum, varsayımsal bir mfc 3.1, MFC31 dll adı.dll yerine. mfc dll özel bir sürümünü üretmeyi mfc kaynak kodunu değiştirirseniz, yine, lütfen farklı bir ad (ve tercihen olmadan "mfc") adı kullanın.
Teknik notlar numarasına göre |nbsp; Teknik notlar kategorisine göre