Upravit

Sdílet prostřednictvím


Nejčastější dotazy k knihovně DLL

Může knihovna MFC DLL vytvořit více vláken?

S výjimkou během inicializace může knihovna MFC DLL bezpečně vytvořit více vláken, pokud používá funkce místního úložiště vlákna Win32 (TLS), jako je TlsAlloc k přidělení místního úložiště vlákna. Pokud však knihovna MFC DLL používá __declspec(thread) k přidělení místního úložiště vlákna, klientská aplikace musí být implicitně propojena s knihovnou DLL. Pokud klientská aplikace explicitně odkazuje na knihovnu DLL, volání LoadLibrary nebude úspěšně načíst knihovnu DLL. Další informace o místních proměnných vláken v knihovnách DLL naleznete v tématu vlákno.

Knihovna MFC DLL, která během spuštění vytvoří nové vlákno MFC, přestane reagovat, když je načtena aplikací. To zahrnuje vždy, když se vlákno vytvoří voláním AfxBeginThread nebo CWinThread::CreateThread uvnitř:

  • Odvozený InitInstanceCWinAppobjekt v běžné knihovně MFC DLL.

  • Zadaná DllMain nebo RawDllMain funkce v běžné knihovně MFC DLL.

  • Zadaná DllMain nebo RawDllMain funkce v knihovně DLL rozšíření MFC.

Může vícevláknová aplikace přistupovat k knihovně MFC DLL v různých vláknech?

Vícevláknové aplikace mají přístup k běžným knihovnám MFC DLL, které dynamicky propojují s rozšiřujícími knihovnami MFC a rozšiřujícími knihovnami DLL z různých vláken. Aplikace má přístup k běžným knihovnám MFC DLL, které staticky propojují knihovnu MFC z více vláken vytvořených v aplikaci.

Existují nějaké třídy nebo funkce MFC, které nelze použít v knihovně MFC DLL?

Rozšiřující knihovny DLL používají CWinAppodvozenou třídu klientské aplikace. Nesmí mít vlastní CWinAppodvozenou třídu.

Běžné knihovny MFC DLL musí mít -odvozenou CWinApptřídu a jeden objekt této třídy aplikace, stejně jako aplikace MFC. CWinApp Na rozdíl od objektu aplikace CWinApp nemá objekt knihovny DLL hlavní čerpadlo zprávy.

Mějte na paměti, že protože CWinApp::Run mechanismus se nevztahuje na knihovnu DLL, aplikace vlastní hlavní čerpadlo zpráv. Pokud knihovna DLL otevře bezmodální dialogová okna nebo má vlastní okno hlavního rámce, hlavní čerpadlo zprávy aplikace musí volat rutinu exportovanou knihovnou DLL, která pak volá CWinApp::PreTranslateMessage členskou funkci objektu aplikace knihovny DLL.

Jaké techniky optimalizace mám použít ke zlepšení výkonu klientské aplikace při načítání?

Pokud je vaše knihovna DLL běžnou knihovnou MFC, která je staticky propojená s knihovnou MFC, změní se na běžnou knihovnu MFC DLL, která je dynamicky propojená s knihovnou MFC, zmenšuje velikost souboru.

Pokud knihovna DLL obsahuje velký počet exportovaných funkcí, použijte k exportu funkcí (místo použití__declspec(dllexport)) soubor .def a pro každou exportovanou funkci použijte atribut NONAME souboru .def. Atribut NONAME způsobí, že se uloží pouze pořadová hodnota, nikoli název funkce v tabulce exportu knihovny DLL, což zmenšuje velikost souboru.

Knihovny DLL, které jsou implicitně propojené s aplikací, se načtou při načítání aplikace. Pokud chcete zvýšit výkon při načítání, zkuste knihovnu DLL rozdělit na různé knihovny DLL. Umístěte všechny funkce, které volající aplikace potřebuje okamžitě po načtení do jedné knihovny DLL a mají volající aplikaci implicitně propojit s danou knihovnou DLL. Umístěte další funkce, které volající aplikace nepotřebuje okamžitě do jiné knihovny DLL a mají aplikaci explicitně propojit s danou knihovnou DLL. Další informace naleznete v tématu Propojení spustitelného souboru s knihovnou DLL.

V mé běžné knihovně MFC DLL nedochází k nevrácení paměti, ale můj kód vypadá dobře. Jak zjistím nevracení paměti?

Jednou z možných příčin nevracení paměti je, že MFC vytváří dočasné objekty, které se používají uvnitř funkcí obslužné rutiny zpráv. V aplikacích MFC se tyto dočasné objekty automaticky vyčistí ve CWinApp::OnIdle() funkci, která je volána mezi zpracováním zpráv. V knihovnách MFC s dynamickým propojením (DLL) se OnIdle() ale funkce automaticky nevolá. V důsledku toho se dočasné objekty automaticky nevyčistí. Chcete-li vyčistit dočasné objekty, musí knihovna DLL explicitně volat OnIdle(1) pravidelně.