Директива #import (C++)
Блок, относящийся только к языку C++
Используется для включения сведений из библиотеки типов. Содержимое библиотеки типов преобразовано в классы C++, в основном описывающие интерфейсы модели COM.
#import "filename" [attributes]
#import <filename> [attributes]
Параметры
filename
Задает тип библиотеки для импорта. filename может принимать следующие значения:Имя файла, содержащего библиотеку типов, например OLB-, TLB- или DLL-файла. Ключевое слово file:, может предшествовать имени каждого файла.
ИД программы элемента управления в библиотеке типов. Ключевое слово progid: может предшествовать каждому идентификатору программы. Например:
#import "progid:my.prog.id.1.5"
Дополнительные сведения об идентификаторах progid см. на странице Задание ИД локализации и номера версии.
Обратите внимание, что при компилировании с использованием межкомпилятора в 64-разрядной операционной системе компилятор сможет прочитать только куст 32-разрядного реестра. Может потребоваться использовать собственный 64-разрядный компилятор для создания и регистрации 64-разрядной библиотеки типов.
Идентификатор библиотеки типов. Ключевое слово libid:, может предшествовать каждому идентификатору библиотеки. Например:
#import "libid:12341234-1234-1234-1234-123412341234" version("4.0") lcid("9")
Если не указать версию или код языка, то правила, которые применяются к progid: также применяются к libid:.
Исполняемый файл (.exe).
Файл библиотеки (DLL), содержащий ресурс библиотеки типов (например, OCX).
Составной документ, содержащую библиотеку типов.
Любой другой формат файла, который может быть понятным для API LoadTypeLib.
attributes
Один или несколько атрибутов #import. Используйте в качестве разделителя атрибутов пробел или запятую. Например:#import "..\drawctl\drawctl.tlb" no_namespace, raw_interfaces_only
-или-
#import "..\drawctl\drawctl.tlb" no_namespace raw_interfaces_only
Заметки
Порядок поиска имени файла
имя файла при необходимости предваряется спецификацией каталога. Имя файла должно указывать на существующий файл. Различие между двумя синтаксисами — это порядок, в котором препроцессор ищет файлы библиотеки типов, когда путь определен не полностью.
Форма синтаксиса |
Действие |
---|---|
Форма в кавычках |
Указывает препроцессору искать файлы библиотеки типов сначала в каталоге файла, содержащего оператор #import, а затем в каталогах любых файлов, которые включают (#include) этого файла. Затем препроцессор выполняет поиск по путям, показанным ниже. |
Форма с угловыми скобками |
Указывает препроцессору искать файлы библиотеки типов по следующим путям.
|
Определение идентификатора локализации и номер версии
При определении идентификатора программы можно также указать идентификатор программы локализации и номер версии. Например:
#import "progid:my.prog.id" lcid("0") version("4.0)
Если не указать идентификатор локализации, идентификатор программы выбирается по следующим правилам.
Если имеется только один ИД локализации, используется он.
Если имеется несколько идентификаторов локализации, используется первый из них с номером версии 0, 9 или 409.
Если имеется несколько идентификаторов локализации и ни один из них не равен 0, 9 или 409, используется последний.
Если не указать номер версии, используется последняя версия.
Файлы заголовков, созданные импортом
#import создает два файла заголовка, которые реконструируют содержимое библиотеки типов в исходном коде на языке C++. Основной файл заголовка аналогичен файлу, создаваемому компилятором MIDL, но с дополнительными создаваемыми компилятором кодом и данными. Основной файл заголовка имеет такое же базовое имя, что и библиотека типов, с расширением .TLH. Вторичный файл заголовка имеет такое же базовое имя, что и библиотека типов, с расширением .TLI. Он содержит реализации созданных компилятором функций-членов и включен (#include) в соответствующий файл заголовка.
Если импортировать свойство dispinterface, использующее параметры byref, #import не создает оператор __declspec (property) для функции.
Оба файла заголовка помещаются в выходной каталог, заданный параметром /Fo (имя объектного файла). Затем они считываются и компилируются компилятором, как если бы основной файл заголовка назывался директивой #include.
Следующие оптимизации компилятора выполняется с помощью директивы #import.
Файл заголовка, когда создан, получает ту же отметку времени, что и библиотека типов.
При обработке #import компилятор проверяет, существует ли заголовок и находится ли он в актуальном состоянии. Если да, повторно создавать его не требуется.
Директива #import также участвует в минимальном перестроении и может быть помещена в предкомпилированный файл заголовка. Дополнительные сведения см. в разделе Создание файлов предкомпилированных заголовков.
Основной файл заголовка библиотеки типов
Основной файл заголовка библиотеки типов состоит из 7 разделов:
Наименование заголовка: состоит из комментариев, оператора #include для COMDEF.H (определяющего некоторые стандартные макросы, используемые в заголовке), и других разнообразных сведений о настройке.
Прямые ссылки и объекты typedef. Состоит из двух структур, таких как struct IMyInterface и typedef.
Объявления интеллектуального указателя. Класс шаблона _com_ptr_t — это реализация интеллектуального указателя, которая инкапсулирует указатели интерфейса и исключает необходимость вызова функций AddRef, ReleaseQueryInterface. Кроме того, он скрывает вызов CoCreateInstance при создании нового COM-объекта. В этом разделе используется оператор _COM_SMARTPTR_TYPEDEF макроса для задания объектов typedef интерфейсов модели COM, чтобы функционировать как специализации шаблона класса шаблонов _com_ptr_t. Например, для интерфейса IMyInterface TLH-файл будет содержать следующее:
_COM_SMARTPTR_TYPEDEF(IMyInterface, __uuidof(IMyInterface));
который будет развернут компилятором следующим образом.
typedef _com_ptr_t<_com_IIID<IMyInterface, __uuidof(IMyInterface)> > IMyInterfacePtr;
Тип IMyInterfacePtr можно затем использовать вместо начального указателя интерфейса IMyInterface*. Следовательно, нет необходимости вызывать различные функции-члены IUnknown
Объявления Typeinfo: в основном состоит из определений классов и других элементов, предоставляющих отдельные элементы typeinfo, возвращенные ITypeLib:GetTypeInfo. В этом разделе каждый объект typeinfo из библиотеки типов отражается в заголовке в форме, которая определяется информацией TYPEKIND.
Необязательное прежнее определение GUID: содержит инициализации именованных констант GUID. Эти имена формы CLSID_CoClass и IID_Interface, схожие с создаваемыми компилятором MIDL.
Оператор #include для заголовка второстепенной библиотеки типов.
Стандартный нижний колонтитул: в настоящее время содержит #pragma pack(pop).
Все разделы, за исключением стандартного раздела верхнего колонтитула и стандартного раздела нижнего колонтитула, заключены в пространство имен, имя которого задается оператором library в исходном файле IDL. Можно использовать имена из заголовков библиотек типов путем явной квалификации с именем пространства имен или путем включения следующего оператора:
using namespace MyLib;
сразу после оператора #import в исходном коде.
Пространство имен может быть подавлено с помощью атрибута no_namespace директивы #import. Однако подавление пространства имен может привести к конфликтам имен. Пространство имен может быть переименовано атрибутом rename_namespace.
Компилятор предоставляет полный путь к любой зависимости библиотеки типов, необходимой библиотеке типов, которая его в данный момент обрабатывает. Путь записывается в форме комментариев в заголовке библиотеки типов (.TLH), который компилятор создает для каждой обрабатываемой библиотеки типов.
Если библиотека типов содержит ссылки на типы, определенные в других библиотеках типов, TLH-файл включает комментарии следующей сортировки:
//
// Cross-referenced type libraries:
//
// #import "c:\path\typelib0.tlb"
//
Фактическое имя файла в комментарии #import — это полный путь к библиотеке типов, на которые имеются перекрестные ссылки, в том виде, в котором они сохранены в реестре. При возникновении ошибок, которые вызваны отсутствующими определения типа, проверьте комментарии в элементе .TLH, чтобы узнать, какие зависимые библиотеки типов может потребоваться импортировать в первую очередь. Самыми вероятными ошибками являются синтаксические (например, C2143, C2146, C2321), C2501 (отсутствуют спецификаторы decl) и C2433 ("inline" не разрешается использовать в объявлении данных) при компиляции TLI-файла.
Необходимо определить, какие из комментариев зависимости в противном случае не предоставляются для заголовков системы, и затем предоставить директиву #import в некоторый момент перед директивой #import зависимой библиотеки типов для разрешения ошибки.
Дополнительные сведения см. в статье базы знаний "Методы программы-оболочки #import могут вызвать нарушение прав доступа" (Q242527) или "Ошибки компилятора при использовании #import с XML" (Q269194). Статьи базы знаний можно найти на компакт-диске библиотеки MSDN или на веб-сайте https://support.microsoft.com/support/.
Атрибуты #import
#import также может включать один или несколько атрибутов. Эти атрибуты указывают, что компилятор изменяет содержимое заголовка библиотеки типов. Символ обратной косой черты (\) можно использовать, чтобы включить дополнительные строки в единственный оператор #import. Например:
#import "test.lib" no_namespace \
rename("OldName", "NewName")
Дополнительные сведения см. в разделе Атрибуты #import (C++).
Завершение блока, относящегося только к языку C++