Düzenle

Aracılığıyla paylaş


DLL ile ilgili sık sorulan sorular

MFC DLL birden çok iş parçacığı oluşturabilir mi?

Başlatma işlemi dışında, iş parçacığı yerel depolama alanı ayırmak için TlsAlloc gibi Win32 iş parçacığı yerel depolama (TLS) işlevlerini kullandığı sürece MFC DLL güvenli bir şekilde birden çok iş parçacığı oluşturabilir. Ancak, bir MFC DLL iş parçacığı yerel depolama ayırmak için kullanıyorsa __declspec(thread) , istemci uygulamasının örtük olarak DLL'ye bağlı olması gerekir. İstemci uygulaması açıkça DLL'ye bağlanırsa, LoadLibrary çağrısı DLL'yi başarıyla yüklemez. DLL'lerdeki iş parçacığı yerel değişkenleri hakkında daha fazla bilgi için bkz . iş parçacığı.

Başlatma sırasında yeni bir MFC iş parçacığı oluşturan bir MFC DLL,bir uygulama tarafından yüklendiğinde yanıt vermeyi durdurur. Bu, çağrılarak AfxBeginThread veya CWinThread::CreateThread içinde bir iş parçacığı oluşturulduğunda şunları içerir:

  • Normal InitInstance bir CWinAppMFC DLL'sindeki türetilmiş nesnenin örneği.

  • Normal MFC DLL'sinde sağlanan DllMain veya RawDllMain işlevi.

  • MFC uzantısı DLL'sinde sağlanan DllMain veya RawDllMain işlevi.

Çok iş parçacıklı bir uygulama, MFC DLL'ye farklı iş parçacıklarında erişebilir mi?

Çok iş parçacıklı uygulamalar, farklı iş parçacıklarından MFC ve MFC uzantısı DLL'lerine dinamik olarak bağlanan normal MFC DLL'lerine erişebilir. Bir uygulama, uygulamada oluşturulan birden çok iş parçacığından MFC'ye statik olarak bağlanan normal MFC DLL'lerine erişebilir.

MFC DLL'sinde kullanılamayabilecek MFC sınıfları veya işlevleri var mı?

Uzantı DLL'leri istemci uygulamasının CWinApptüretilmiş sınıfını kullanır. Kendi CWinApptüretilmiş sınıflarına sahip olmamalıdır.

Normal MFC DLL'leri, MFC uygulaması gibi - türetilmiş bir sınıfa ve bu uygulama sınıfının tek bir nesnesine sahip CWinAppolmalıdır. CWinApp Bir uygulamanın nesnesinden farklı olarak, CWinApp DLL nesnesinin ana ileti pompası yoktur.

Mekanizma bir DLL için geçerli olmadığından uygulamanın ana ileti pompasına sahip olduğunu CWinApp::Run unutmayın. DLL, modeless iletişim kutularını açarsa veya kendi ana çerçeve penceresine sahipse, uygulamanın ana ileti pompası DLL tarafından dışarı aktarılan bir yordamı çağırmalıdır ve bu da DLL'nin uygulama nesnesinin üye işlevini çağırır CWinApp::PreTranslateMessage .

Yükleme sırasında istemci uygulamasının performansını geliştirmek için hangi iyileştirme tekniklerini kullanmalıyım?

DLL'niz statik olarak MFC'ye bağlı normal bir MFC DLL'yse, bunu MFC'ye dinamik olarak bağlı olan normal bir MFC DLL'ye değiştirmek dosya boyutunu küçültür.

DLL'de çok sayıda dışarı aktarılan işlev varsa, işlevleri dışarı aktarmak için bir .def dosyası kullanın (kullanmak __declspec(dllexport)yerine) ve dışarı aktarılan her işlevde .def dosyası NONAME özniteliğini kullanın. NONAME özniteliği, işlev adının DEĞIL yalnızca sıralı değerin DLL'nin dışarı aktarma tablosunda depolanmasına neden olur ve bu da dosya boyutunu küçültür.

Uygulama yüklendiğinde örtük olarak bir uygulamaya bağlı DLL'ler yüklenir. Yükleme sırasında performansı geliştirmek için DLL'yi farklı DLL'lere bölmeyi deneyin. Çağıran uygulamanın ihtiyaç duyduğu tüm işlevleri bir DLL'ye yüklendikten hemen sonra yerleştirin ve çağıran uygulamanın bu DLL'ye örtük olarak bağlanmasına sahip olun. Çağıran uygulamanın ihtiyaç duymadığı diğer işlevleri hemen başka bir DLL'ye yerleştirin ve uygulamanın bu DLL'ye açıkça bağlanmasını sağlayın. Daha fazla bilgi için bkz . Yürütülebilir dosyayı DLL'ye bağlama.

Normal MFC DLL'imde bellek sızıntısı var, ancak kodum iyi görünüyor. Bellek sızıntısını nasıl bulabilirim?

Bellek sızıntısının olası nedenlerinden biri, MFC'nin ileti işleyici işlevlerinde kullanılan geçici nesneler oluşturmasıdır. MFC uygulamalarında, bu geçici nesneler iletilerin işlenmesi arasında çağrılan işlevde otomatik olarak temizlenir CWinApp::OnIdle() . Ancak MFC dinamik bağlantı kitaplıklarında (DLL) OnIdle() işlev otomatik olarak çağrılmaz. Sonuç olarak, geçici nesneler otomatik olarak temizlenmez. Geçici nesneleri temizlemek için DLL'nin düzenli aralıklarla açıkça çağrısı OnIdle(1) yapması gerekir.