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


Директива #import (C++)

Специфика C++

Используется для включения сведений из библиотеки типов. Содержимое библиотеки типов преобразовано в классы C++, в основном описывающие интерфейсы модели COM.

Синтаксис

#import "filename" [атрибуты]
<#import имя> файла [атрибуты]

Параметры

filename
Задает тип библиотеки для импорта. Имя файла может быть одним из следующих типов:

  • Имя файла, содержащего библиотеку типов, например OLB-, TLB- или DLL-файла. Ключевое слово, file:может предшествовать каждому имени файла.

  • ИД программы элемента управления в библиотеке типов. Ключевое слово, progid:может предшествовать каждому прогидированному. Например:

    #import "progid:my.prog.id.1.5"
    

    Дополнительные сведения о progids см. в разделе "Указание идентификатора локализации" и номера версии.

    При использовании 32-разрядного кросс-компилятора в 64-разрядной операционной системе компилятор может считывать только 32-разрядный куст реестра. Может потребоваться использовать собственный 64-разрядный компилятор для создания и регистрации 64-разрядной библиотеки типов.

  • Идентификатор библиотеки типов. Ключевое слово , libid:может предшествовать каждому идентификатору библиотеки. Например:

    #import "libid:12341234-1234-1234-1234-123412341234" version("4.0") lcid("9")
    

    Если вы не указываете или lcidне применяете libid:version к ней правила. progid:

  • Исполняемый файл (.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)

Если идентификатор локализации не указан, progid выбирается в соответствии со следующими правилами:

  • Если существует только один идентификатор локализации, он используется.

  • Если существует несколько идентификаторов локализации, используется первый с номером версии 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 макроса для установки типдифик интерфейсов 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

#import может включать один или несколько атрибутов. Эти атрибуты указывают, что компилятор изменяет содержимое заголовка библиотеки типов. Символ обратной косой черты\ () можно использовать для включения дополнительных строк в одну инструкцию #import . Например:

#import "test.lib" no_namespace \
   rename("OldName", "NewName")

Дополнительные сведения см. в #import атрибутах.

END C++ Specific

См. также

Директивы препроцессора
Поддержка COM компилятора