Jenter Алекс
Шрифт:
СТАТЬЯ
Введение в COM
Часть 2
Автор: michael dunn
Перевод: Илья Простакишин
Источник: The Code Project
Каждый COM-интерфейс наследуется от интерфейса IUnknown. Имя выбрано не совсем удачно, поскольку этот интерфейс не является "неизвестным" (unknown). Это имя всего лишь означает, что если вы имеете указатель на интерфейс COM-объекта IUnknown, то вы не можете знать, какой объект им владеет (реализует), поскольку интерфейс IUnknown есть в каждом COM-объекте.
IUnknown включает три метода:
1. AddRef – заставляет COM-объект увеличивать (инкрементировать) свой счетчик обращений. Вы должны использовать этот метод, если была сделана копия указателя на интерфейс и нужно обеспечить возможность использования двух указателей – копии и оригинала. Мы не будем использовать метод AddRef в этой статье, т.к. для рассматриваемых здесь задач он не нужен.
2. Release – сообщает COM-объекту о необходимости уменьшения (декремента) счетчика обращений. Смотрите предыдущий пример, чтобы понять, как нужно использовать Release.
3. QueryInterface – запрашивает указатель на интерфейс COM-объекта. Используется если CO-класс содержит не один, а несколько интерфейсов.
Вы уже видели пример использования Release, но как же действует QueryInterface? Когда вы создаете COM-объект с помощью CoCreateInstance, вы получаете указатель на интерфейс. Если COM-объект включает более одного интерфейса (не считая IUnknown), вы должны использовать метод QueryInterface для получения дополнительных указателей на интерфейсы, которые вам нужны. Посмотрим на прототип QueryInterface:
Значения параметров:
iid | IID интерфейса, который вам нужен. |
ppv | Адрес указателя на интерфейс. QueryInterface возвращает указатель на интерфейс через этот параметр, если не произошло никаких ошибок. |
Продолжим наш пример с ярлыком. CO-класс для создания ярлыков включает интерфейсы IShellLink и IPersistFile. Если у вас уже есть указатель на IShellLink – pISL, то вы можете запросить интерфейс IPersistFile у COM-объекта с помощью следующего кода:
Затем вы тестируете hr с помощью макроса SUCCEEDED. Это нужно, чтобы узнать, сработал ли метод QueryInterface. Если все нормально, то можно использовать новый указатель pIPF, так же как и любой другой интерфейсный указатель. Затем вам нужно вызвать метод pIPF->Release для сообщения COM-объекту, что вы закончили работу с интерфейсом и он вам больше не нужен.
Я хочу остановиться на некоторых моментах, касающихся работы со строками при написании программ в COM.
Всякий раз, когда метод COM возвращает строку, он делает это, используя формат Unicode. Unicode это таблица символов, также как и ASCII, только все символы в ней занимают 2 байта (в ANSI – один байт). Если вы хотите получить строку в более удобном виде, то ее нужно преобразовать в тип TCHAR.
TCHAR и функции, начинающиеся с _t (например, _tcscpy) были разработаны для управления строками Unicode и ANSI с использованием одинакового исходного кода. Наверняка, вы раньше писали программы с использованием ANSI-строк и ANSI-функций, поэтому далее в этой статье я буду обращаться к типу char, вместо TCHAR, чтобы лишний раз вас не смущать. Однако, вы должны знать, что есть такой тип – TCHAR, хотя бы для того, чтобы не задавать лишних вопросов, когда встретите его в программах, написанных другими разработчиками.
Когда вы получаете строку из метода COM, вы можете преобразовать ее в строку char одним из следующих способов:
1. Вызвать функцию API WideCharToMultiByte.
2. Вызвать функцию CRT wcstombs.
3. Использовать конструктор CString или оператор присваивания (только в MFC).
4. Использовать макрос преобразования ATL.
С другой стороны, вы можете лишь хранить строку Unicode, если с ней не требуется делать что-либо еще. Если вы создаете консольное приложение, то вывод на экран строки Unicode можно осуществить с помощью глобальной переменной std::wcout, например:
Однако, имейте ввиду, что wcout предполагает, что все "входящие" строки имеют формат Unicode, поэтому если вы имеете любую "нормальную" строку, то для вывода нужно использовать std::cout. Если вы используете строковые литералы, для перевода в Unicode ставьте перед ними символ L, например:
Если вы используете строки Unicode, вы должны знать о следующих ограничениях: