Допускается ли создание в библиотеке DLL MFC нескольких потоков?
За исключением инициализации, библиотека DLL MFC может безопасно создавать несколько потоков, если в ней используются функции локального хранилища (TLS) потока Win32, такие как TlsAlloc, для выделения локального хранилища потоков. Однако если библиотека DLL MFC использует __declspec(thread)
для выделения локального хранилища потоков, клиентское приложение должно быть неявно связано с библиотекой DLL. Если клиентское приложение явно ссылается на библиотеку DLL, вызов LoadLibrary не загрузит библиотеку DLL. Дополнительные сведения о локальных переменных потока в библиотеках DLL см. в разделе о потоке.
Библиотека DLL MFC, которая создает новый поток MFC во время запуска, перестает отвечать на запросы при загрузке приложением. Это происходит каждый раз при создании потока путем вызова AfxBeginThread
или CWinThread::CreateThread
внутри следующих элементов:
InitInstance
объекта, производного отCWinApp
, в обычной библиотеке DLL MFC.Переданная функция
DllMain
или RawDllMain в обычной библиотеке DLL MFC.Переданная функция
DllMain
или RawDllMain в библиотеке DLL расширения MFC.
Допускается ли обращение к библиотеке DLL MFC из многопоточного приложения в различных потоках?
Многопоточные приложения могут получать доступ к обычным библиотекам DLL MFC, которые динамически связываются с библиотеками DLL расширения MFC и MFC из разных потоков. Приложение может получить доступ к обычным библиотекам DLL MFC, которые статически связываются с MFC из нескольких потоков, созданных в приложении.
Какие классы и функции MFC не могут использоваться в библиотеке DLL MFC?
Библиотеки DLL расширения используют класс, производный от CWinApp
, клиентского приложения. Они не должны иметь собственный класс, производный от CWinApp
.
Обычные библиотеки DLL MFC должны иметь класс, производный от CWinApp
, и один объект этого класса приложения так же, как и приложение MFC. В отличие от объекта CWinApp
приложения, у объекта CWinApp
библиотеки DLL нет основного генератора сообщений.
Обратите внимание, что механизм CWinApp::Run
не применяется к библиотеке DLL, так как в приложении есть основной генератор сообщений. Если библиотека DLL открывает немодальные диалоговые окна или имеет собственное основное окно кадра, основной генератор сообщений приложения должен вызвать подпрограмму, экспортированную библиотекой DLL, которая, в свою очередь, вызывает функцию-член CWinApp::PreTranslateMessage
объекта приложения библиотеки DLL.
Методы увеличения скорости загрузки клиентского приложения
Если библиотека DLL является обычной библиотекой DLL MFC, которая статически связана с MFC, то изменение ее на обычную библиотеку DLL MFC, которая динамически связана с MFC, сокращает размер файла.
Если в библиотеке DLL содержится большое количество экспортированных функций, используйте DEF-файл для экспорта функций (вместо использования __declspec(dllexport)
), а также атрибут NONAME DEF-файла для каждой экспортированной функции. Атрибут NONAME приводит к сохранению только порядкового значения, а не имени функции в таблице экспорта библиотеки DLL, что сокращает размер файла.
Библиотеки DLL, которые неявно связаны с приложением, загружаются при загрузке приложения. Чтобы повысить производительность при загрузке, попробуйте разделить библиотеку DLL на разные библиотеки DLL. Помещайте все функции, необходимые вызывающему приложению сразу после загрузки, в одну библиотеку DLL, и настройте вызывающее приложение для неявной связи с этой библиотекой DLL. Помещайте остальные функции, которые не нужны вызывающему приложению сразу, в другую библиотеку DLL, и настройте вызывающее приложение для явной связи с этой библиотекой DLL. Дополнительные сведения см. в разделе Связывание исполняемого файла с библиотекой DLL.
В обычной библиотеке DLL MFC обнаружена утечка памяти, однако видимые ошибки в коде отсутствуют. Как найти утечку памяти?
Одной из возможных причин утечки памяти является тот факт, что MFC создает временные объекты, используемые внутри функций обработчика сообщений. В приложениях MFC эти временные объекты автоматически очищаются в функции CWinApp::OnIdle()
, которая вызывается между сообщениями обработки. Однако в библиотеках динамической компоновки (DLL) MFC функция OnIdle()
не вызывается автоматически. В результате временные объекты не очищаются автоматически. Чтобы очистить временные объекты, библиотека DLL должна периодически явно вызывать OnIdle(1)
.