Директива #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
иRelease
QueryInterface
функций. Он также скрывает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