Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Содержание сайт... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Создание отчето... 65061
Модуль Forms 64836
Пример работы с... 63235
ТЕХНОЛОГИИ ДОСТ... 61550
Имитационное мо... 57390
Реклама
Сейчас на сайте
Гостей: 6
На сайте нет зарегистрированных пользователей

Пользователей: 13,081
новичок: Abdukarimov A
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Поиск пути в графе заданном списками инцедентности на Turbo Pascal
Моделирование станции технического обслуживания на GPSS + Отчет
Медиа плейер на Delphi + Пояснительная записка

Реклама



Подписывайся на YouTube канал о программировании, что бы не пропустить новые видео!

ПОДПИСЫВАЙСЯ на канал о программировании
Исключения



СОМ имеет специфическую поддержку выбрасывания (throwing) исключительных ситуаций из реализации методов. Поскольку в языке C++ не существует двоичного стандарта для исключений, СОМ предлагает явные API-функции для выбрасывания и перехвата объектов СОМ-исключений:
// throw an exception
// возбуждаем исключения
HRESULT SetErrorInfo([in] ULONG reserved, //
m.b.z. [in] IErrorlnfo *pei);
// catch an exception
// перехватываем исключение
HRESULT GetErrorInfo([in] ULONG reserved, // m.b.z.
[out] IErrorInfo **ppei);



Процедура SetErrorInfo вызывается из реализации метода, чтобы связать объект исключения с текущим логическим потоком (logical thread) [1] . GetErrorInfo выбирает объект исключения из текущего логического потока и сбрасывает исключение, так что следующие вызовы GetErrorInfo возвратят SFALSE, показывая тем самым, что необработанных исключений нет. Как следует из приведенных ниже подпрограмм, объекты исключений должны поддерживать по крайней мере интерфейс IErrorInfo:
[ object, uuid(1CF2B120-547D-101B-8E65-08002B2BD119) ]
interface IErrorInfo: IUnknown
{
// get IID of interface that threw exception
// получаем IID того интерфейса, который возбудил исключение
HRESULT GetGUID([out] GUID * pGUID);
// get class name of object that threw exception
// получаем имя класса того объекта, который возбудил исключение
HRESULT GetSource([out] BSTR * pBstrSource);
// get human-readable description of exception
// получаем читабельное описание исключения
HRESULT GetDescription([out] BSTR * pBstrDescription);
// get WinHelp filename of documentation of error
// получаем имя файла WinHelp, содержащего документацию об ошибке
HRESULT GetHelpFile([out] BSTR * pBstrHelpFile);
// get WinHelp context ID for documentation of error
// получаем контекстный идентификатор WinHelp для документации ошибки
HRESULT GetHelpContext([out] DWORD * pdwHelpContext);
}



Специальные объекты исключений могут выбрать другие специфические для исключений интерфейсы в дополнение к IErrorInfo .
СОМ предусматривает по умолчанию реализацию IErrorInfo , которую можно создать с использованием API-функции СОМ CreateErrorInfo :
HRESULT CreateErrorInfo([out] ICreateErrorInfo **ppcei);
В дополнение к IErrorInfo объекты исключений по умолчанию открывают интерфейс ICreateErrorInfo , чтобы позволить пользователю инициализировать состояние нового исключения:
[ object, uuid(22F03340-547D-101B-8E65-08002B2BD119) ]
interface ICreateErrorInfo: IUnknown
{
// set IID of interface that threw exception
// устанавливаем IID интерфейс, который возбудил исключение
HRESULT SetGUID([in] REFGUID rGUID);
// set class name of object that threw exception
// устанавливаем классовое имя объекта, который возбудил исключение
HRESULT SetSource([in, string] OLECHAR* pwszSource);
// set human-readable description of exception
// устанавливаем читабельное описание исключения
HRESULT SetDescription([in, string] OLECHAR* pwszDesc);
// set WinHelp filename of documentation of error
// устанавливаем имя файла WinHelp, содержащего документацию об ошибке
HRESULT SetHelpFile([in, string] OLECHAR* pwszHelpFile);
// set WinHelp context ID for documentation of error
// устанавливаем идентификатор контекста WinHelp для документации ошибки
HRESULT SetHelpContext([in] DWORD dwHelpContext);
}



Заметим, что этот интерфейс просто позволяет пользователю заполнить объект исключения пятью основными атрибутами, доступными из интерфейса IErrorInfo .
Следующая реализация метода выбрасывает СОМ-исключение своему вызывающему объекту, используя объект исключений по умолчанию:
STDMETHODIMP PugCat::Snore(void)
{
if (this->IsAsleep())
// ok to perform operation?
// можно ли выполнять операцию?
return this->DoSnore();
//do operation and return
// выполняем операцию и возвращаемся
//otherwise create an exception object
// в противном случае создаем объект исключений
ICreateErrorInfo *рсеi = 0; HRESULT hr = CreateErrorInfo(&pcei);
assert(SUCCEEDED(hr));
// initialize the exception object
// инициализируем объект исключений
hr = pcei->SetGUID(II DIPug);
assert(SUCCEEDED(hr));
hr = pcei->SetSource(OLESTR(«PugCat»));
assert(SUCCEEDED(hr));
hr = pcei->SetDescription(OLESTR("I am not asleep !"));
assert(SUCCEEDED(hr));
hr = pcei->SetHelpFile(OLESTR(«C:\\PugCat.hlp»));
assert(SUCCEEDED(hr));
hr = pcei->SetHelpContext(5221);
assert(SUCCEEDED(hr));
// «throw» exception
// «выбрасываем» исключение
IErrorInfo *pei = 0;
hr = pcei->QueryInterface(II DIErrorInfo , (void**)&pei);
assert(SUCCEEDED(hr));
hr = SetErrorInfo(0, pei);
// release resources and return a SEVERIT YERROR result
// высвобождаем ресурсы и возвращаем результат
// SEVERITY ERROR (серьезность ошибки)
pei->Release();
pcei->Release();
return PUGEPUGNOTASLEEP;
}



Отметим, что поскольку объект исключений передается в процедуру SetErrorInfo , СОМ сохраняет ссылку на исключение до тех пор, пока оно не будет «перехвачено» вызывающим объектом, использующим GetErrorInfo .
Объекты, которые сбрасывают исключения СОМ, должны использовать интерфейс ISupportErrorInfo , чтобы показывать, какие интерфейсы поддерживают исключения. Этот интерфейс используется клиентами, чтобы установить, верный ли результат дает GetErrorInfo [2] . Этот интерфейс предельно прост:
[ object, uuid(DFOB3060-548F-101B-8E65-08002B2BD119) ]
interface ISupportErrorInfo: IUnknown
{
HRESULT InterfaceSupportsErrorInfo([in] REFIID riid);
}



Предположим, что класс PugCat , рассмотренный в этой главе, сбрасывает исключения из каждого поддерживаемого им интерфейса. Тогда его реализация будет выглядеть так:
STDMETHODIMP PugCat::InterfaceSupportsErrorInfo(REFIID riid)
{
if (riid == II DIAnimal || riid == IID ICat || riid == II DIDog || riid == IID IPug) return SOK;
else return S FALSE;
}



Ниже приведен пример клиента, который надежно обрабатывает исключения, используя ISupportErrorInfo и GetErrorInfo :
void TellPugToSnore(/*[in]*/ IPug *pPug)
{
// call a method
// вызываем метод
HRESULT hr = pPug->Snore();
if (FAILED(hr))
{
// check to see if object supports СОМ exceptions
// проверяем, поддерживает ли объект исключения СОМ
ISupportErrorInfo *psei = 0;
HRESULT hr2 =pPug->QueryInterface( IIDISupportErrorInfo, (void**)&psei);
if (SUCCEEDED(hr2))
{
// check if object supports СОМ exceptions via IPug methods
// проверяем, поддерживает ли объект исключения СОМ через методы
IPug hr2 = psei->InterfaceSupportsErrorInfo(IIDIPug);
if (hr2 == SOK)
{
// read exception object for this logical thread
// читаем объект исключений для этого логического потока
IErrorInfo *реi = 0;
hr2 = GetErrorInfo(0, &pei);
if (hr2 == SOK)
{
// scrape out source and description strings
// извлекаем строки кода и описания
BSTR bstrSource = 0, bstrDesc = 0;
hr2 = pei->GetDescription(&bstrDesc);
assert(SUCCEEDED(hr2));
hr2 = pei->GetSource(&bstrSource);
assert(SUCCEEDED(hr2));
// display error information to end-user
// показываем информацию об ошибке конечному пользователю
MessageBoxW(0, bstrDesc ? bstrDesc : L"«, bstrSource ? bstrSource : L»", MBOK);
// free resources
// высвобождаем ресурсы
SysFreeString(bstrSource);
SysFreeString(bstrDesc);
pei->Release();
}
}
psei->Release();
}
}
if (hr2!= SOK)
// something went wrong with exception
// что-то неладно с исключением
MessageBox(0, «Snore Failed», «IPug», MBOK);
}



Довольно просто отобразить исключения СОМ в исключения C++, причем в любом месте. Определим следующий класс, который упаковывает объект исключений СОМ и HRESULT в один класс C++:
struct COMException
{
HRESULT mhresult;
// hresult to return
// hresult для возврата IErrorInfo *mpei;
// exception to throw
// исключение для выбрасывания
COMException(HRESULT hresult, REFIID riid, const OLECHAR *pszSource, const OLECHAR *pszDesc, const OLECHAR *pszHelpFile = 0, DWORD dwHelpContext = 0)
{
// create and init an error info object
// создаем и инициализируем объект информации об ошибке
ICreateErrorInfo *рсеi = 0;
HRESULT hr = CreateErrorInfo(&pcei);
assert(SUCCEEDED(hr));
hr = pcei->SetGUID(riid);
assert(SUCCEEDED(hr));
if (pszSource) hr=pcei->SetSource(constcast(pszSource));
assert(SUCCEEDED(hr));
if (pszDesc) hr=pcei->SetDescription(constcast(pszDesc));
assert(SUCCEEDED(hr));
if (pszHelpFile) hr=pcei->SetHelpFile(constcast(pszHelpFile));
assert(SUCCEEDED(hr));
hr = pcei->SetHelpContext(dwHelpContext);
assert(SUCCEEDED(hr));
// hold the HRESULT and IErrorInfo ptr as data members
// сохраняем HRESULT и указатель IErrorInfo как элементы данных
mhresult = hresult;
hr=pcei->QueryInterface(IIDIErrorInfo, (void**)&mpei);
assert(SUCCEEDED(hr));
pcei->Release();
}
};



С использованием только что приведенного С++-класса COMException показанный выше метод Snore может быть модифицирован так, чтобы он преобразовывал любые исключения C++ в исключения СОМ:
STDMETHODIMP PugCat::Snore(void)
{
HRESULT hrex = SOK;
try
{
if (this->IsAsleep()) return this->DoSnore();
else throw COMException(PUGEPUGNOTASLEEP, IIDIPug, OLESTR(«PugCat»), OLESTR(«I am not asleep!»));
}
catch (COMException& ce)
{
// a C++ COMException was thrown
// было сброшено исключение COMException C++
HRESULT hr = SetErrorInfo(0, ce.mpei);
assert(SUCCEEDED(hr));
ce.mpei->Release();
hrex = ce.mhresult;
}
catch (…)
{
// some unidentified C++ exception was thrown
// было выброшено какое-то неидентифицированное исключение C++
COMException ex(EFAIL, IIDIPug, OLESTR(«PugCat»), OLESTR(«A C++ exception was thrown»));
HRESULT hr = SetErrorInfo(0, ex.mpei);
assert(SUCCEEDED(hr));
ex.mpei->Release();
hrex = ex.mhresult;
}
return hrex;
}



Заметим, что реализация метода заботится о том, чтобы не позволить чисто С++-исключениям переходить через границы метода. Таково безусловное требование СОМ.
Опубликовал Kest July 13 2009 01:46:02 · 0 Комментариев · 7171 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
GamesBase 3.0
Панель поиска
Игра "Астероиды" ...
UmEdit
Стелтинг Стивен, ...
SMExport
Киллер окон
Delphi 2006 - Спр...
Fig [Исходник на ...
MicroGPSS Studen ...
Пример работы с б...
Пользовательская...
Аватары в комме...
DeleteEdit
Delphi. Учимся на...
Мод "проверочный ...
Программирование ...
Самоучитель PHP 4
Панель Наша Кнопка
TsHintManager

Топ загрузок
Приложение Клие... 100466
Delphi 7 Enterp... 86614
Converter AMR<-... 20077
GPSS World Stud... 12635
Borland C++Buil... 11753
Borland Delphi ... 8555
Turbo Pascal fo... 7037
Visual Studio 2... 4998
Калькулятор [Ис... 4759
FreeSMS v1.3.1 3541
Случайные статьи
Задача о коммивояж...
Структура сообщени...
Illegal assignment
Язык ассемблера
Pikavippi s-pankin...
ChatSession.cpp
Язык С: операции н...
Отдых
Распутывание вино...
Восьмеричные деревья
Метод Чёрчмена-Акофа
Структура модуля
Министерство нацио...
В общем виде вызов...
ПРИЛОЖЕНИЕ 4. Блок...
Вскрытие Xbox
Рис. 1.24. Предвар...
Настраиваемые конс...
Режим нагрева водо...
Настройка фонового...
Механизм условных ...
Раздел описания ме...
Выбор наилучших ал...
Язык программирова...
передаваемых по ГВС
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?