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


Экспортирование и импортирование с использованием AFX_EXT_CLASS

Библиотеки расширений используют макросы AFX_EXT_CLASS для экспортирования классов. Исполняемые файлы, связанные с библиотекой расширения, используют данный макрос для импортирования классов.Кроме макроса AFX_EXT_CLASS файл заголовка, который используется для построения библиотеки расширения, также может применяться вместе с исполняемыми файлами, связанными с библиотеками DLL.

В файле заголовка для библиотеки DLL ключевое слово AFX_EXT_CLASS добавляется в объявление класса следующим образом:

class AFX_EXT_CLASS CMyClass : public CDocument
{
// <body of class>
};

Библиотека MFC определяет макрос в качестве __declspec(dllexport), когда определяются символы предпроцессора _AFXDLL и _AFXEXT.Макрос определяется в качестве __declspec(dllimport), когда определяется _AFXDLL и не определяется _AFXEXT.После завершения процесса определения символ предпроцессора _AFXDLL показывает, что общая версия MFC используется исполняемым целевым файлом (библиотекой DLL или приложением).Определение и символа _AFXDLL, и _AFXEXT указывает на то, что исполняемый целевой файл является библиотекой расширения.

Во время экспортирования из библиотеки расширения AFX_EXT_CLASS определяется в качестве __declspec(dllexport). Это позволяет экспортировать все классы, не заменяя в DEF-файле декорированные имена символов класса.В приведенном примере этот метод используется библиотекой MFC DLLHUSK.

Несмотря на то, что можно избежать создания DEF-файла и всех декорированных имен для классов с этим методом, DEF-файл делает работу более эффективной, поскольку имена экспортируются по порядковым номерам.Чтобы использовать метод экспортирования DEF-файла, введите следующий код в начале и в конце файла заголовка.

#undef AFX_DATA
#define AFX_DATA AFX_EXT_DATA
// <body of your header file>
#undef AFX_DATA
#define AFX_DATA
Предупреждающее замечаниеВнимание

Будьте осторожны при экспортировании подставляемых функций, поскольку они могут вызвать конфликты версий.Встроенная функция расширяется в код приложения; поэтому, если в дальнейшем вы переписываете эту функцию, она не обновится, если не выполнить повторную компиляцию приложения.Обычно функции библиотек DLL обновляются без повторного построения приложений, в которых они используются.

Экспортирование отдельных членов в класс

Время от времени может возникать необходимость экспортирования отдельных членов в класс.Например, при экспортировании класса, производного от CDialog, возможно, потребуется экспортировать только конструктора и вызов DoModal.Для выполнения экспортирования отдельных членов можно также использовать AFX_EXT_CLASS на них.

Примеры.

class CExampleDialog : public CDialog
{
public:
   AFX_EXT_CLASS CExampleDialog();
   AFX_EXT_CLASS int DoModal();
   ...
   // rest of class definition
   ...
};

Поскольку экспортируются не все элементы класса, то можно столкнуться с другой проблемой из-за способа работы макросов библиотеки MFC.Несколько вспомогательных макросов MFC объявляют или определяют члены данных.Следовательно, эти члены данных также можно экспортировать из библиотеки DLL.

Например, при построении библиотеки расширения макрос DECLARE_DYNAMIC определяется следующим образом:

#define DECLARE_DYNAMIC(class_name) \
protected: \
   static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
   static AFX_DATA CRuntimeClass class##class_name; \
   virtual CRuntimeClass* GetRuntimeClass() const; \

Строка, которая начинается со статического AFX_DATA, объявляет о статическом объекте внутри класса.Чтобы правильно экспортировать класс и получить доступ к данным исполняемого клиентского файла во время выполнения, необходимо экспортировать статический объект.Поскольку статический объект объявляется вместе с модификатором AFX_DATA, необходимо определить AFX_DATA в качестве __declspec(dllexport) при построении библиотеки DLL, а также определить в качестве __declspec(dllimport) при построении исполняемого клиентского файла.Если объект AFX_EXT_CLASS уже определен таким образом, необходимо переопределить AFX_DATA для соответствия объекту AFX_EXT_CLASS в пределах определения класса.

Примеры.

#undef  AFX_DATA
#define AFX_DATA AFX_EXT_CLASS

class CExampleView : public CView
{
   DECLARE_DYNAMIC()
   // ... class definition ...
};

#undef  AFX_DATA
#define AFX_DATA

Поскольку MFC всегда использует символ AFX_DATA для членов данных, которые он определяет в пределах своего макроса, эта технология работает для всех подобных скриптов.Например, она работает для DECLARE_MESSAGE_MAP.

ПримечаниеПримечание

При экспортировании всего класса, а не отдельно выбранных членов, статические члены данных экспортируются автоматически.

9xyb5w93.collapse_all(ru-ru,VS.110).gifВыполняемые задачи

9xyb5w93.collapse_all(ru-ru,VS.110).gifДополнительные сведения

См. также

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

Экспорт из библиотеки DLL