|
Программирование >> Перегруженные имена функций и идентификаторы
Первое на что следует обратить внимание - это на строчку файла sampl.tlh: namespace SAMPLLib { Это означает, что компилятор помещает описание классов в отдельное пространство имён, соответствующее имени библиотеки типов. Это является необходимым при использовании нескольких библиотек типов с одинаковыми именами классов, такими, например, как IDocument. При желании, имя пространства имён можно изменить или запретить его генерацию совсем: #import sampl.dll rename namespace( NewNameSAMPLLib ) #import sampl.dll no namespace Теперь рассмотрим объявление метода Method: ISamplObjectPtr Method (const variant t & Var, bstr t Str); Здесь мы видим использование компилятором классов поддержки COM. К таким классам относятся следующие. com error. Этот класс используется для обработки исключительных ситуаций, генерируемых библиотекой типов или каким либо другим классом поддержки (например, класс variant t будет генерировать это исключение, если не сможет произвести преобразование типов). com ptr t. Этот класс определяет гибкий указатель для использования с интерфейсами COM и применяется при создании и уничтожении объектов. variant t. Инкапсулирует тип даннгх VARIANT и может значительно упростить код приложения, поскольку работа с данными VARIANT напрямую является несколько трудоёмкой. bstr t. Инкапсулирует тип данных BSTR. Этот класс обеспечивает встроенную обработку процедур распределения и освобождения ресурсов, а также других операций. Нам осталось уточнить природу класса ISamplObjectPtr. Мы уже говорили о классе com ptr t. Он используется для реализации smart-указателей на интерфейсы COM. Мы будем часто использовать этот класс, но не будем делать этого напрямую. Директива #import самостоятельно генерирует определение smart-указателей. В нашем примере это сделано следующим образом. Smart pointer typedef declarations COM SMARTPTR TYPEDEF(ISamplObject, uuidof(ISamplObject)); Это объявление эквивалентно следующему: typedef com ptr t<ISamplObject,& uuidof(ISamplObject)> ISamplObjectPtr Использование smart-указателей позволяет не думать о счётчиках сс1лок на объекты COM, т.к. методы AddRef и Release интерфейса lUnknown вызываются автоматически в перегруженных операторах класса com ptr t. Помимо прочих, этот класс имеет следующий перегруженный оператор: Interface* operator->() const throw( com error); где Interface - тип интерфейса, в нашем случае - это ISamplObject. Таким образом, мы сможем обращаться к свойствам и методам нашего COM объекта. Вот как будет выглядеть пример использования директивы #import для нашего примера: #import sampl.dll void SamplFunc () SAMPLLib::ISamplObjectPtr obj; obj.CreateInstance(L SAMPLLib.SamplObject ); SAMPLLib::ISamplObjectPtr obj2 = obj->Method(1l,L 12345 ); obj->Prop = SAMPLLib::SamplType2; obj2->Prop = obj->Prop; Как видно из примера создавать объекты COM с использованием классов, сгенерированных директивой #import, достаточно просто. Во-первых, необходимо объявить smart-указатель на тип создаваемого объекта. После этого для создания экземпляра нужно вызвать метод Createlnstance класса com ptr t, как показано в следующих примерах: SAMPLLib::ISamplObjectPtr obj; obj.CreateInstance(L SAMPLLib.SamplObject ); obj.CreateInstance( uuidof(SamplObject)); Можно упростить этот процесс, передавая идентификатор класса в конструктор указателя: SAMPLLib::ISamplObjectPtr obj(L SAMPLLib.SamplObject ); или SAMPLLib::ISamplObjectPtr obj( uuidof(SamplObject)); Прежде чем перейти к примерам, нам необходимо рассмотреть обработку исключительных ситуаций. Как говорилось ранее, директива #import использует для генерации исключительных ситуаций класс com error. Этот класс инкапсулирует генерируемые значения HRESULT, а также поддерживает работу с интерфейсом IErrorInfo для получения более подробной информации об ошибке. Внесём соответствующие изменения в наш пример: #import sampl.dll void SamplFunc () try { using namespace SAMPLLib; ISamplObjectPtr obj(L SAMPLLib.SamplObject ); ISamplObjectPtr obj2 = obj->Metod(1l,L 12345 ); obj->Prop = SAMPLLib::SamplType2; obj2->Prop = obj->Prop; } catch ( com error& er) { printf( com error:\n Error : %08lX\n ErrorMessage: %s\n Description : %s\n Source : %s\n , er.Error(), (LPCTSTR) bstr t(er.ErrorMessage()), (LPCTSTR) bstr t(er.Description()), (LPCTSTR) bstr t(er.Source())); При изучении файла sampl.tli хорошо видно как директива #import генерирует исключения. Это происходит всегда при выполнении следующего условия:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |