Распределённая обработка данных на ЭВМ

Автор работы: Пользователь скрыл имя, 17 Января 2013 в 22:52, контрольная работа

Описание работы

Разработать программу для следующего сценария:
Объявить интерфейсы IX, IY, IZ . Объявить интерфейс IUnknown.
Реализация компонента. Класс СА реализует компонент, поддерживающий интерфейсы IX и IY. Реализовать QueryInterface описанным выше способом. Функцию CreateInstance определить после класса CA. Клиент использует ее, чтобы создать компонент, представляемый при помощи СА, и получить указатель на IUnknown этого компонента. После CreateInstance определить IID для интерфейсов. (Для того, чтобы определить IID для IUnknown компоновать с UUID.LIB).

Файлы: 1 файл

Кафедра.docx

— 67.61 Кб (Скачать файл)

 

 

 

 

 

 

 

 

 

 

 

Кафедра «Информационные системы  и технологии»

 

 

 

Контрольная работа №1

 

 

 

 

 

Распределённая обработка данных на ЭВМ

 

 

 

 

 

Вариант № ____

 

 

 

 

 

Выполнил       студент группы

 

Проверил       

 

 

 

 

 

 

 

2012

 

Контрольная работа №1

QueryInterface

 

Цель работы:

Разработать программу для следующего сценария:

Объявить  интерфейсы IX, IY, IZ . Объявить интерфейс IUnknown.

Реализация  компонента. Класс СА реализует компонент, поддерживающий интерфейсы IX и IY. Реализовать QueryInterface описанным выше способом. Функцию CreateInstance определить после класса CA. Клиент использует ее, чтобы создать компонент, представляемый при помощи СА, и получить указатель на IUnknown этого компонента. После CreateInstance определить IID для интерфейсов. (Для того, чтобы определить IID для IUnknown компоновать с UUID.LIB).

Реализация  клиента, роль которого выполняет main. Клиент начинает с создания компонента при помощи CreateInstance. CreateInstance возвращает указатель на интерфейс IUnknown компонента. Клиент при помощи QueryInterface запрашивает через интерфейс IUnknown указатель на интерфейс IX компонента. Анологично запросить и IY. Использовать эти указатели для доступа к функциям-членам. Запросить интерфейс IZ. QueryInterface возвращает код ошибки, так как СА не реализует IZ. Далее Клиент запрашивает указатель на интерфейс IY через указатель на интерфейс IX, pIX. Поскольку компонент поддерживает IY, этот запрос будет успешным, и клиент сможет использовать возвращенный указатель на интерфейс IY так же, как он использовал первый указатель. Затем клиент запрашивает интерфейс IUnknown через указатель на IY. Поскольку все интерфейсы COM наследуют IUnknown, этот запрос должен быть успешным, причем возвращенный указатель совпадет с первым указателем, так как . QueryInterface возвращает один и тот же указатель на все запросы к IUnknown.

Теоретические сведения:

В COM клиент взаимодействует с компонентом с помощью интерфейса

IUnknown, который определен в заголовочном файле UNKWN.H:

 

Interface IUnknown

{

virtual HREZULT --stdcall QueryInterface( const IID&iid,

void * * ppv) = 0 ;

virtual ULONG --stdcall Addref( ) = 0 ;

 

virtual ULONG --stdcall Release( ) = 0 ;

};

 

Функцию с именем QueryInterface клиент вызывает, чтобы определить, поддерживает ли компонент некоторый интерфейс. У функции QueryInterface два параметра. Первый параметр – идентификатор интерфейса. Второй параметр - адрес, по которому QueryInterface помещает указатель на искомый интерфейс.

QueryInterface возвращает HREZULT – 32-разрядный код результата.

QueryInterface может возвратить либо S_OK, либо E_NOINTERFACE. Клиент не должен прямо сравнивать возвращаемое QueryInterface значение с этими константами; для проверки надо использовать макросы SUCCEEDED или FAILED.

Получение указателя на IUnknown

Для получения  указателя на IUnknown использовать функцию, например, CreateInstance которая создает компонент и возвращает указатель на IUnknown:

IUnknown * CreateInstance( )

Реализация  функции CreateInstance:

IUnknown * pI = static_cast<IX*>(new CA) ;

PI->Addref( ) ;

Return pI ;

Использование QueryInterface.

Предположим, что у нас есть указатель на IUnknown, pI. Чтобы определить, можно ли использовать некоторый другой интерфейс, мы вызываем QueryInterface, передавая ей идентификатор нужного нам интерфейса. Если QueryInterface отработала успешно, мы можем пользоваться указателем:

 

void foo(IUnknown* pI)

{

// Определить  указатель на интерфейс

IX* pIX=NULL;

 

// Запросить  интерфейс IX

HREZULT hr = pI-> QueryInterface(IID_IX, (void**)&pIX) ;

 

// Проверить  значение результата

if (SUCCEEDED(hr))

{

// Использовать  интерфейс

pIXFx( ) ;

}

}

 

Реализация  QueryInterface.

 

Запишем QueryInterface для следующего компонента, реализуемого классом CA:

 

Interface IX : IUnknown { /*…*/ } ;

Interface IY : IUnknown { /*…*/ } ;

Class CA : public IX, public IY { /*…*/ } ;

 

Следующий фрагмент кода реализует QueryInterface для класса, приведенного выше фрагмента кода.

 

HREZULT --stdcall CA:: QueryInterface( const IID&iid, void * * ppv);

{

if (iid ==IID_IUnknown)

{

// Клиент  запрашивает интерфейс IUnknown

*ppv = static_cast<IX*>(this) ;

}

else if (iid ==IID_IX)

{

// Клиент  запрашивает интерфейс IX

 

*ppv = static_cast<IX*>(this) ;

}

else if (iid ==IID_IY)

{

// Клиент  запрашивает интерфейс IY

 

*ppv = static_cast<IY*>(this) ;

}

else

{

 

// Мы не  поддерживаем запрашиваемый клиентом  интерфейс.

// Установить  возвращаемый указатель в NULL.

*ppv = NULL ;

return E_NOINTERFACE ;

}

static_cast< IUnknown*>(*ppv)->AddRef( ) ;

return S_OK ;

}

 

 

Текст программы:

 

#include "stdafx.h"

#include "iostream.h"

#include "objbase.h"

#include "conio.h"

 

void trace(const char* msg) { cout << msg << endl; }

// Интерфейсы

interface IX : IUnknown

{

virtual void __stdcall Fx() = 0;

};

interface IY : IUnknown

{

virtual void __stdcall Fy() = 0;

};

interface IZ : IUnknown

{

virtual void __stdcall Fz() = 0;

};

// Предварительные объявления GUID

extern const IID IID_IX;

extern const IID IID_IY;

extern const IID IID_IZ;

//

 

 

 

 

// Компонент

class CA : public IX, public IY

{

// Реализация IUnknown

virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv);

virtual ULONG __stdcall AddRef() { return 0; }

virtual ULONG __stdcall Release() { return 0; }

// Реализация интерфейса IX

virtual void __stdcall Fx() { cout << "Fx" << endl; }

// Реализация интерфейса IY

virtual void __stdcall Fy() { cout << "Fy" << endl; }

};

HRESULT __stdcall CA::QueryInterface(const IID& iid, void** ppv)

{

if (iid == IID_IUnknown)

{

trace("QueryInterface: Vernyt' ykazatel' na IUnknown");

*ppv = static_cast<IX*>(this);

}

else if (iid == IID_IX)

{

trace("QueryInterface: Vernyt' ykazatel' na IX");

*ppv = static_cast<IX*>(this);

}

else if (iid == IID_IY)

{

trace("QueryInterface: Vernyt' ykazatel' na IY");

*ppv = static_cast<IY*>(this);

}

else

{

trace("QueryInterface: Interface No!");

*ppv = NULL;

return E_NOINTERFACE;

}

reinterpret_cast<IUnknown*>(*ppv)->AddRef();

return S_OK;

}

// Функция создания

IUnknown* CreateInstance()

{

IUnknown* pI = static_cast<IX*>(new CA);

pI->AddRef();

return pI;

}

// IID

// {32bb8320-b41b-11cf-a6bb-0080c7b2d682}

static const IID IID_IX =

{0x32bb8320, 0xb41b, 0x11cf,

{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}};

// {32bb8321-b41b-11cf-a6bb-0080c7b2d682}

static const IID IID_IY =

{0x32bb8321, 0xb41b, 0x11cf,

{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}};

// {32bb8322-b41b-11cf-a6bb-0080c7b2d682}

static const IID IID_IZ =

{0x32bb8322, 0xb41b, 0x11cf,

{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}};

 

 

// Клиент

int main()

{

HRESULT hr;

trace("Client: Polychit' ykazatel' na IUnknown");

IUnknown* pIUnknown = CreateInstance();

trace("Client: Polychit' ykazatel' na IX");

IX* pIX = NULL;

hr = pIUnknown->QueryInterface(IID_IX, (void**)&pIX);

if (SUCCEEDED(hr))

{

trace("Client: IX polychen");

pIX->Fx(); // Использовать  интерфейс IX

}

trace("Client: Polychit' ykazatel na IY");

IY* pIY = NULL;

hr = pIUnknown->QueryInterface(IID_IY, (void**)&pIY);

if (SUCCEEDED(hr))

{

trace("Client: IY polychen");

pIY->Fy(); // Использовать  интерфейс IY

}

trace("Client: Zaprosit' nepodderjivaemuy interface");

IZ* pIZ = NULL;

hr = pIUnknown->QueryInterface(IID_IZ, (void**)&pIZ);

if (SUCCEEDED(hr))

{

trace("Client: Interface IZ polychen");

pIZ->Fz();

}

else

{

trace("Client: No Interface IZ");

}

trace("Client: Polychit' Interface IY cherez Interface IX");

IY* pIYfromIX = NULL;

hr = pIX->QueryInterface(IID_IY, (void**)&pIYfromIX);

if (SUCCEEDED(hr))

{

trace("Client: IY polychen");

pIYfromIX->Fy();

}

trace("Client: Polechit' Interface IUnknown cherez IY");

IUnknown* pIUnknownFromIY = NULL;

hr = pIY->QueryInterface(IID_IUnknown, (void**)&pIUnknownFromIY);

if (SUCCEEDED(hr))

{

cout << "Sovpadaut li ykazateli na IUnknown? ";

if (pIUnknownFromIY == pIUnknown)

{

cout << "Yes, pIUnknownFromIY == pIUnknown" << endl;

}

else

{

cout << "No, pIUnknownFromIY != pIUnknown" << endl;

}

}

 

 

 

// Удалить компонент

delete pIUnknown;

getch();

return 0;

}

 

Результат работы программы:

 

 

Вывод:

 

В данном задании объявили интерфейсы IX, IY, IZ, и интерфейс IUnknown.

Реализовали компонент. Класс СА который реализует  компонент, поддерживающий интерфейсы IX и IY. Реализовали QueryInterface. Функцию CreateInstance, которая определяется после класса CA. Клиент использует ее, чтобы создать компонент, представляемый при помощи СА, и получили указатель на IUnknown этого компонента.


Информация о работе Распределённая обработка данных на ЭВМ