Поделиться через


Инициализация библиотек расширения

Поскольку в библиотеках расширения, в отличие от обычных библиотек DLL, не используется производный от CWinApp объект, следует добавить код инициализации и завершения в функцию DllMain, созданную с помощью мастера DLL MFC.

C помощью мастера автоматически создается следующий код библиотеки расширения. В приведенном ниже коде вместо PROJNAME следует использовать имя создаваемого проекта.

#include "stdafx.h"
#include <afxdllx.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static AFX_EXTENSION_MODULE PROJNAMEDLL = { NULL, NULL };

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
   if (dwReason == DLL_PROCESS_ATTACH)
   {
      TRACE0("PROJNAME.DLL Initializing!\n");
      
      // Extension DLL one-time initialization
      AfxInitExtensionModule(PROJNAMEDLL, 
                                 hInstance);

      // Insert this DLL into the resource chain
      new CDynLinkLibrary(Dll3DLL);
   }
   else if (dwReason == DLL_PROCESS_DETACH)
   {
      TRACE0("PROJNAME.DLL Terminating!\n");
   }
   return 1;   // ok
}

За счет создания нового объекта CDynLinkLibrary во время инициализации обеспечивается экспорт объектов CRuntimeClass или ресурсов из библиотеки расширения в клиентское приложение.

Если предполагается использование библиотеки расширения в одной или нескольких обычных библиотеках DLL, необходимо экспортировать функцию, с помощью которой создается объект CDynLinkLibrary. Эту функцию необходимо вызывать в каждой из обычных библиотек, в которых используется библиотека расширения. Чтобы использовать классы и функции, экспортированные из библиотеки расширения, необходимо вызвать эту функцию инициализации в функции-члене InitInstance объекта, производного от класса CWinApp обычной библиотеки DLL.

В функции DllMain, автоматически создаваемой с помощью мастера DLL MFC, при обращении к функции AfxInitExtensionModule регистрируются классы времени выполнения модуля (структуры CRuntimeClass), а также производства объектов (объекты COleObjectFactory), которые используются при создании объекта CDynLinkLibrary. Проверьте значение, возвращаемое функцией AfxInitExtensionModule. Если функция AfxInitExtensionModule возвращает нулевое значение, в функции DllMain также следует возвратить нулевое значение.

Если библиотека расширения явно связана с исполняемым файлом (то есть в исполняемом файле вызывается функция AfxLoadLibrary для связывания с библиотекой DLL), следует добавить вызов функции AfxTermExtensionModule со значением DLL_PROCESS_DETACH. Эта функция используется в MFC для очистки библиотеки расширения после отсоединения от нее всех процессов (выполняется при завершении процесса или выгрузке библиотеки DLL с помощью функции AfxFreeLibrary). В случае неявного связывания библиотеки расширения с приложением вызывать функцию AfxTermExtensionModule не требуется.

В приложениях, явно связанных с библиотеками расширения, при освобождении библиотеки следует вызвать функцию AfxTermExtensionModule. Если в таком приложении используется несколько потоков, следует вызвать функции AfxLoadLibrary и AfxFreeLibrary (вместо функций Win32 LoadLibrary и FreeLibrary). При использовании функций AfxLoadLibrary и AfxFreeLibrary гарантируется, что выполнение кода запуска и завершения работы при загрузке и выгрузке библиотеки расширения, не приведет к повреждению глобального состояния MFC.

Поскольку на момент вызова функции DllMain инициализация библиотеки MFCx0.dll полностью завершается, можно выделить память и вызвать функции MFC в функции DllMain (в отличие от 16-разрядной версии MFC).

В библиотеках расширения многопоточность реализуется за счет обработки значений DLL_THREAD_ATTACH и DLL_THREAD_DETACH функции DllMain. Эти значения передаются в функцию DllMain в случае присоединения потоков к библиотеке DLL и отсоединения от нее соответственно. Чтобы обеспечить хранение в библиотеке DLL индексов локальной памяти потока (TLS) для каждого присоединенного к ней потока, вызовите функцию TlsAlloc в процессе присоединения библиотеки DLL.

Обратите внимание, что в файле заголовка Afxdllx.h содержатся специальные определения для структур, используемых в библиотеках расширения, например AFX_EXTENSION_MODULE и CDynLinkLibrary. Этот файл заголовка необходимо включить в библиотеку расширения.

Примечание

Обратите внимание, что в файле Stdafx.h не допускается определение или отмена определения каких-либо макросов _AFX_NO_XXX.Дополнительные сведения см. в статье базы знаний "PRB. Проблемы, возникающие при определении _AFX_NO_XXX" (на английском языке, ИД статьи — 140751).Статьи базы знаний можно найти в библиотеке MSDN или с http://search.support.microsoft.com/.

Пример функции инициализации, в которой реализуется обработка многопоточности, см. в разделе Использование локальной памяти потока в библиотеке DLL в пакете Windows SDK. Обратите внимание, что в примере используется функция точки входа LibMain, которой следует присвоить имя DllMain, что позволит использовать ее в библиотеках времени выполнения MFC и C.

В примере MFC DLLHUSK показан порядок использования функций инициализации.

Выберите действие.

Дополнительные сведения

См. также

Основные понятия

Инициализация библиотеки DLL