Экспортирование и импортирование с использованием 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.
![]() |
---|
При экспортировании всего класса, а не отдельно выбранных членов, статические члены данных экспортируются автоматически. |
Выполняемые задачи
Экспорт из библиотеки DLL с использованием __declspec(dllexport)
Экспорт функций C++ для использования в исполняемых файлах, исходный код которых написан на языке C