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


Директива #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) этого файла. Затем препроцессор выполняет поиск по путям, показанным ниже.

Форма с угловыми скобками

Указывает препроцессору искать файлы библиотеки типов по следующим путям.

  1. Список путей переменной среды PATH

  2. Список путей переменной среды LIB

  3. Путь, указанный параметром компилятора /I (дополнительные каталоги включения), за исключением его компилятор выполняет поиск библиотеки типов, для которой задана ссылка из другой библиотеки типов с помощью атрибута no_registry.

Определение идентификатора локализации и номер версии

При определении идентификатора программы можно также указать идентификатор программы локализации и номер версии. Например:

#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++

См. также

Ссылки

Директивы препроцессора

Поддержка компилятора COM