ИНФОРМАЦИЯ: Использование в коде _declspec(dllimport) & _declspec(dllexport)

ВНИМАНИЕ! Перевод данной статьи был выполнен не человеком, а с помощью программы машинного перевода, разработанной корпорацией Майкрософт. Корпорация Майкрософт предлагает вам статьи, переведенные как людьми, так и средствами машинного перевода, чтобы у вас была возможность ознакомиться со статьями базы знаний KB на родном языке. Однако машинный перевод не всегда идеален. Он может содержать смысловые, синтаксические и грамматические ошибки, подобно тому как иностранец делает ошибки, пытаясь говорить на вашем языке. Корпорация Майкрософт не несет ответственности за неточности, ошибки и возможный ущерб, причиненный в результате неправильного перевода или его использования. Корпорация Майкрософт также часто обновляет средства машинного перевода.

Эта статья на английском языке: 132044
Эта статья помещена в архив. Она предлагается "как есть" и обновляться не будет.
Аннотация
Эта статья дополняет сведения, описанные в следующей статьев Microsoft Knowledge Base:
107501 ИНФОРМАЦИЯ: __export заменены __declspec в 32-разрядных Visual C++
В этой статье обсуждаются преимущества и механизм использования_declspec(dllimport) и _declspec(dllexport) в приложении.
Дополнительная информация
32-Разрядной версии Visual C++ использует _declspec(dllimport) и_declspec(dllexport) заменить ключевое слово __export, ранее использовался в16-разрядных версиях Visual C++.

Необходимо использовать _declspec(dllimport) для кода для компиляцииправильно но применение позволяет компилятору создать код лучшего качества. Вкомпилятор может создать код лучшего качества, потому что он знает точно лифункция существует в библиотеке DLL или нет, поэтому компилятор может создавать кодыПропустите уровень косвенного обращения, которые обычно являются в функциивызов, библиотеке.

С правильнымРазделе EXPORTS DEF-файла, не является _declspec(dllexport)соблюдения дополнительных условий. _declspec(dllexport) был добавлен обеспечивают простой способ для экспортаиз функции.EXE или.Библиотеки DLL без использования.DEF-файла.

Оставшаяся часть этой статьи предоставляет достаточно низкоуровневого тщательнойобсуждение этих вопросов.

Формат переносимого исполняемого файла Win32 разработан для минимизации числастраницы, которые необходимо прикоснулись к импортов. Чтобы сделать это, он помещает всеИмпорт адресов для любой программы в одном месте, называется адрес импортаТаблица. Это позволяет загрузчику модифицировать только одна или две страницы, когдадоступ к этим imports.

С помощью _declspec(dllimport) для вызовов функций

В следующем примере кода предполагается func1 является функция, которая хранится вОтдельно от библиотеки DLL.EXE-файла, содержащего функцию main().

Без _declspec(dllimport) учитывая этот код:
void main(void) {    func1();}				
компилятор создает код, который выглядит следующим образом:
call func1				
и компоновщик преобразует вызов в примерно следующим образом:
call 0x4000000         ; The address of 'func1'.				
Если «func1» существует в другой библиотеке DLL, компоновщик не может разрешить это непосредственнотак как нет способа узнать адрес «func1» — в ней. В 16-разрядноесредах компоновщик добавляет адрес этого кода в список в.EXEчто бы исправление загрузчик, во время выполнения правильный адрес. В 32-разряднойсредах компоновщик создает преобразователь, для которой известныадрес. Преобразователь выглядит следующим образом:
   0x40000000:    jmp DWORD PTR __imp_func1				
Здесь __imp_func1 — это адрес для разъема func1 в адрес импортаТаблица.EXE-файла. Таким образом, все адреса известны компоновщику. ВЗагрузчик имеет только для обновления.Таблица адресов импорта EXE файла во время загрузкидля всех объектов, для правильной работы.

Таким образом, с помощью _declspec(dllimport) предпочтительнее, так как он лучше, еслиКомпоновщик не создавать преобразователь, если его нет. Преобразователи расширяюткод большего размера (для систем RISC, она может быть несколько инструкций) и могутухудшить эффективность кэша. Если сообщить компилятору функция находится вDLL, он может быть создан непрямой вызов.

Так что теперь этот код:
__declspec(dllimport) void func1(void);void main(void) {    func1();}				
создает следующую инструкцию:
call DWORD PTR __imp_func1				
Нет отсутствует преобразователь и инструкция не jmp, поэтому код меньшего размера ибыстрее.

С другой стороны для вызовов функций в библиотеке DLL не требуется иметьЧтобы использовать непрямой вызов. Вы уже знаете адрес функции. Время иместа необходимо загрузить и хранить адрес функции передкосвенный вызов, поэтому прямой вызов всегда быстрее и меньше. Требуется толькоЧтобы использовать __declspec(dllimport) при вызове функций библиотеки DLL, за пределамисамой библиотеке DLL. Не используйте __declspec(dllimport) для функций в библиотеке DLLПри построении данной Библиотеки.

С помощью _declspec(dllexport)

Корпорация Майкрософт представила __export в версии 16-разрядный компилятор, чтобы разрешитькомпилятор автоматически создает имена экспорта и помещает их в.LIB-файл. ЭтотLIB-файл может использоваться так же, как статический.LIB длясвязи с библиотекой DLL.

Корпорация Майкрософт добавила __declspec(dllexport) для продолжения такого рода. Егопредназначено для добавления директивы экспорта файла объекта, поэтому нет необходимостис.DEF-файла.

Данное преимущество особенно заметно при экспорте декорированных C++имена функций. Поэтому есть не стандартные спецификации для Декорирование именимя экспортируемой функции может отличаться в разных версиях компилятора. ЕслиИспользуйте _declspec(dllexport), перекомпиляция библиотеки DLL и зависимые.EXE файлыЭто необходимо только для учетной записи изменений соглашение об именовании.

Например, можно сделать порядковые номера NONAME и PRIVATE, большинство директив экспортатолько в.DEF-файла, а не способ указания этих атрибутовбез.DEF-файла. Тем не менее с помощью _declspec(dllexport) в дополнение кс помощью.DEF-файла не приводит к ошибкам построения.

В качестве ссылки поиск по Win32 WINBASE.Файл заголовка. Он содержитПримеры основной __declspec(dllexport) и __declspec(dllimport)Использование.

С помощью _declspec(dllexport) и _declspec(dllimport) данных

В случае данных с помощью _declspec(dllimport) является удобства товараУдаляет уровень косвенного обращения. При импорте данных из библиотеки DLL, которые по-прежнемуЧтобы иметь через таблицы адресов импорта. В Win32 дней до_declspec(dllimport), это означало, что нужно было помнить о необходимости выполнения дополнительный уровенькосвенного обращения при доступе к данным, экспортируемой из DLL:
// project.h#ifdef _DLL     // If accessing the data from inside the DLL   ULONG ulDataInDll;else            // If accessing the data from outside the DLL   ULONG *ulDataInDll;#endif				
Затем будет экспортировать данные в вашем.DEF-файла:
// project.defLIBRARY projectEXPORTS    ulDataInDll   CONSTANT				
и доступ к нему вне библиотеки DLL:
if (*ulDataInDll == 0L) {   // Do stuff here}				
Когда помечается данные как __declspec(dllimport), компилятор автоматическисоздается код косвенного обращения. Больше не нужно беспокоиться оописанные выше действия. Как уже говорилось ранее, следует использовать _declspec(dllimport)объявление данных при построении библиотеки DLL. Функции в библиотеке DLLТаблица адресов импорта не будет использовать для доступа к объекту данных. Таким образом,не будет иметь дополнительный уровень косвенного обращения.

Для автоматического экспорта данных из библиотеки DLL, используйте следующее объявление:
__declspec(dllexport) ULONG ulDataInDLL;				

С помощью.DEF-файла

Если решено использовать __declspec(dllimport) вместе с.DEF-файла, можноследует изменить.DEF-файла для использования данных вместо КОНСТАНТЫ для уменьшениявероятность того, что неверный код вызовет ошибку:
// project.defLIBRARY projectEXPORTS    ulDataInDll   DATA				
Следующая диаграмма показывает, почему:
Keyword     Emits in the import lib     ExportsCONSTANT    __imp_ulDataInDll           ulDataInDll            __ulDataInDllDATA        __imp_ulDataInDll           ulDataInDll				
С помощью _declspec (dllimport) и КОНСТАНТЫ перечислены версии __imp_ иВнутреннее имя в.Библиотека импорта LIB DLL, созданный дляРазрешить явное связывание. Использование данных и _declspec(dllimport) перечислены только__imp_ версия имени.

Если используется КОНСТАНТА, либо из следующих конструкций кода может быть использованадля доступа к ulDataInDll:
__declspec(dllimport) ULONG ulDataInDll; /*prototype*/    if (ulDataInDll == 0L)   /*sample code fragment*/ 				
- или -
ULONG *ulDataInDll;      /*prototype*/ if (*ulDataInDll == 0L)  /*sample code fragment*/ 				
Однако при использовании данных в вашей.DEF-файла только код скомпилирован сследующие определения можно получить доступ к переменной ulDataInDll:
__declspec(dllimport) ULONG ulDataInDll;if (ulDataInDll == 0L)   /*sample code fragment*/ 				
Использование КОНСТАНТ более опасными, поскольку если вы забудете использовать дополнительный уровенькосвенного обращения потенциально может открыть таблицы адресов импортауказатель на переменную--не саму переменную. Этот тип проблемычасто может проявиться как нарушение прав доступа, так как таблица адресов импортав настоящее время выполняется только для чтения, компилятор Microsoft и компоновщиков команда разработчиков.

Компоновщик текущего Visual C++ выдает предупреждение при обнаружении CONSTANT вв.DEF-файла для учетной записи для этого случая. Единственным реальным основанием для использованияЯвляется КОНСТАНТОЙ, если невозможно перекомпилировать некоторый объектный файл, где файл заголовкане содержит списка dllimport в прототипе.
Ссылки
Visual C++ Books Online предоставить значительный объем документацииатрибуты класса хранения dllexport и dllimport. Это включает в себя«Атрибуты dllexport и dllimport» и "с помощью dllimport иdllexport в C++ "разделы в главе «Модификаторы относящиеся к Майкрософт»Справочник по языку C++ и в подразделах «Экспорт символов»«Создание библиотеки DLL для Win32» Глава ссылка приемов программирования.Тщательное список щелкните ссылку поиска электронной документации для«dllimport» или «dllexport».

Дополнительные сведения можно найти следующие статьи в MicrosoftБаза знаний:
90530 Экспорт данных из библиотеки DLL или приложения
107501 ИНФОРМАЦИЯ: __export заменены __declspec в 32-разрядных Visual C++

Внимание! Эта статья переведена автоматически

Свойства

Номер статьи: 132044 — последний просмотр: 12/04/2015 11:35:06 — редакция: 8.0

Microsoft Visual C++ 2.0 Professional Edition, Microsoft Visual C++ 5.0 Enterprise Edition, Microsoft Visual C++ 5.0 Professional Edition

  • kbnosurvey kbarchive kbcode kbcompiler kbinfo kbmt KB132044 KbMtru
Отзывы и предложения