Поиск

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

Поскольку слой взаимодействия с СОМ поначалу может несколько ошеломить, давайте на минуту забудем обо всех формальных определениях 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-клиент может использовать для "переговоров" с нашим компонентом и вызова его методов.