Принципы объектно-ориентированного программирования

         

Приступим к делу



Приступим к делу

Поскольку слой взаимодействия с СОМ поначалу может несколько ошеломить, давайте на минуту забудем обо всех формальных определениях j и перейдем к реальному примеру, иллюстрирующему применение ком- / понента СОМ из приложения .NET. По мере продвижения вперед я буду/ давать разъяснение происходящих событий и расскажу, как использовать приобретенные знания в ваших приложениях.

В этом примере мы предположим, что у нас есть СОМ-компонент Airlinelnfo, написанный на Microsoft Visual C++ с ATL. Я не будут освещать здесь все этапы создания этого компонента, потому что хочу сосредоточиться на вопросах, связанных с .NET и С#. Однако я разъясню этот выдающийся код (полный проект Visual C++ находится на CD, прилагаемом к этой книге).

Наш компонент СОМ разработан для того, чтобы выдавать подробности о прибытии рейсов некоторой авиалинии. Для простоты допустим, что компонент возвращает данные для авиалинии Air Scooby 1C 5678, а в случае любой другой авиалинии — ошибку. Я намеренно вставил механизм генерации ошибки, чтобы показать вам, как ошибка, возникшая в компоненте СОМ, может проходить в обратном направлении и перехватываться вызывающим клиентским приложением .NET. Вот IDL для компонента СОМ:

interface lAirlinelnfo : IDispatch {



[id(1), helpstring("method GetAirlineTiming")]

HRESULT GetAirlineTiming([in] BSTR bstrAirline, [out,retval] BSTR* pBstrDetails);

[propget, id(2), helpstring("property LocalTiraeAtOrlando")] HRESULT LocalTimeAtOrlando([out, retval] BSTR •pVal); };

Ничего особенного, даже для самых неопытных разработчиков СОМ. У нас есть интерфейс с именем lAirlinelnfo и двумя методами: GetAirlineTiming и LocalTimeAtOrlando. А теперь взгляните на настоящую реализацию метода GetAirlineTiming:

STDMETHODIMP CAirlineInfo::GetAirlineTiming(BSTR bstrAirline, BSTR *pBstrDetails)

{

\ _bstr_t bstrQueryAirline(bstrAirline); \ if(NULL == pBstrDetails) return E.POINTER;

\ if(_bstr_t("Air Scooby 1C 5678") ==

\ bstrdueryAirline)

\ {

I // Вернуть расписание для этой авиалинии.

\ "pBstrDetails =

| _bstr_t(_T("16:45:00 - Will

arrive at Terminal 3")).copy();

}

else

{

II Вернуть сообщение об ошибке.

return Error(LPCTSTR(_T("Not available" )),

__uuidof(Airlinelnfo),

AIRLINE_NOT_FOUND);

>

return S_OK; }

Метод GetAirlineTiming принимает два аргумента. Первый (bstrAirline) — это строка BSTR, представляющая авиалинию, а второй (pBstrDetails) — выходной параметр, возвращающий информацию о прибытии (местное время и проход для регистрации). В этом методе мы проверяем, равно ли значение входного параметра bstrAirline строке "Air Scooby 1C 5678". Если это так, то мы возвращаем некоторую жестко заданную информацию о прибытии. Если значение не совпадает с ожидаемым, мы вызываем метод ошибки, чтобы вернуть уведомление о том, что поддерживается только одна авиалиния.

Закончив с обзором основ использования компонентов, рассмотрим генерирование метаданных из библиотеки типов компонента (typelib), которые .NET-клиент может использовать для "переговоров" с нашим компонентом и вызова его методов.

 

Содержание раздела