Практическое занятие № 6 Разработка клиента распределённого приложения для
Windows на С++
Цель практического занятия Изучить и освоить разработку клиента распределённого
приложения для Windows, получить практические навыки по разработке сетевых программ на языках С, С++.
Теоретические сведения
В этой работе спроектируем СОМ-клиента, который будет использовать созданный на предыдущем практическом занятии СОМ-сервер СоCаr. Вы осуществите запрос SCM с помощью библиотеки СОМ, будете оперировать с указателями интерфейса, работать с bstr и создавать фабрики класса. Завершится процесс преобразования CoCаr. Вот его этапы:
структура с набором глобальных функций; простой объект C++;
объект C++ с множественными интерфейсами; исполняемая DLL на базе СОМ.
Готовый проект находится в каталоге … \Ch3\CoCarClient3-3.
1. Подготовка рабочего пространства проекта
Создадим новое консольное приложение Win32 с именем CoCarClient, на этот раз выберите simple project (простой проект). Прежде чем использовать CarInProcServer.dll, необходимо внести в рабочее пространство следующие файлы:
-iid.h и iid.cpp. Нужны константы GUID. Вставьте файл СРР в проект;
-interfaces.h. Нужны имена интерфейсов, чтобы определить переменные указателей к ним;
-включите также заголовочные файлы в начало файла
cocarclient.cpp.
44
После копирования этих файлов в подкаталог проекта, можно приступать к созданию кода клиента
#include "interfaces.h" #include "iid.h" #include <iostream.h> int main()
{
return 0;
}
2. Реализация функции main()
Реализуйте в головном блоке следующие функциональные возможности.
// Код клиента на C++ int main(void)
{
//Инициализация подсистемы СОМ
//Получение указателя IClassFactory из CoCarClassFactory
//Вызов Createlnstance() из pICF, запрос IID_ICreateCar из СоСаr
//Выполнение ICreateCar.
//Запрос IID_IStats из указателя ICreateCar или IUnknown
//Вызов DisplayStats() из pIStats QI для IEngine
//Разгоняем машину
// Используя pIStats->GetPetName(), выводим BSTR на консоль,
//информируя пользователя о "кончине" машины
//Освобождаем все полученные указатели интерфейсов
//Завершаем подсистему СОМ
return 0;
}
Большая часть кода клиента совпадает с приложением CоСаrАрр (см. домашнее задание №2). Вот полный листинг:
// Программа СОМ-клиента
//
45
int main()
{
CoInitialize(NULL); HRESULT hr; IClassFactory* pCF = NULL;
ICreateCar* pICreateCar = NULL; IStats* pStats = NULL;
IEngine* pEngine = NULL;
cout << "**********************" << endl; cout << "The Amazing CoCar Client" << endl; cout << "**********************" << endl;
// Получить указатель фабрики класса CoCar.
hr = CoGetClassObject(CLSID_CoCar, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void**)&pCF);
// Создать CoCar & получить ICreateCar.
hr = pCF->CreateInstance(NULL, IID_ICreateCar,(void**)&pICreateCar); pCF ->Release();
if (SUCCEEDED (hr) )
{
pICreateCar->SetMaxSpeed(30) ;
BSTR petName = SysAllocString(L"Shazzam! "); pICreateCar->SetPetName (petName) ; SysFreeString (petName) ;
// Теперь получаем IStats
hr = pICreateCar->QueryInterface(IID_IStats, (void**) SpStats) ; pICreateCar->Release( ) ;
}
if (SUCCEEDED(hr) )
{
//Указываем данные машины и получаем IEngine pStats->DisplayStats( ) ;
hr = pStats->QueryInterface(IID_IEngine, (void**) &pEngine) ;
}
// Разгоняемся!
46
if (SUCCEEDED(hr) ) { int curSp = 0; int maxSp = 0;
pEngine->GetMaxSpeed(&maxSp) ; do{
pEngine->SpeedUp ( ) ; pEngine-X3etCurSpeed(&curSp) ; cout << "Speed is: " << curSp << endl;
}while(curSp <= maxSp) ;
//Преобразуем BSTR в массив char char buff [80];
BSTR bstr; pStats->GetPetName(Sbstr) ;
WideCharToMultiByte (CP_ACP, NULL, bstr, -1, buff, 80, NULL, NULL); cout << buff << " has blown up! Lead Foot!" << endl << endl;
//Убираем за собой
SysFreeString(bstr) ; if (pEngine) pEngine->Release( ) ; if (pStats) pStats->Release( ) ;
}
CoUninitialize(); return 0;
}
Контрольные вопросы
1.Каким образом клиентская программа отыскивает соответствующую серверную программу?
2.Как формируется значение CLSID?
3.Для чего служат переменные типа HRESULT?
47
Практическое занятие № 7 Особенности разработки распределённых приложений для
Windows с применением различных языков
Цель практического занятия Изучить и освоить разработку клиентов распределён-
ных приложений для Windows на различных языках, принципы обеспечения удалённого взаимодействия разноязыковых модулей, получить практические навыки по разработке сетевых программ на языках С, С++.
Теоретические сведения
Эта работа позволяет поэкспериментировать с языковой независимостью модели СОМ. В ней расширяется разработанный ранее сервер CarInProcServer.dll до поддержки информации о типе и применяются файлы, сгенерированные компилятором MIDL. После обновления сервера СоСаr появляется возможность построить клиентские приложения на Visual Basic и Java, а также клиента C++ с использованием директив компилятора СОМ.
Готовые решения находятся в каталогах:
… \Ch4\CarServerTypeInfo: СоСаг с библиотекой типов;
… \Ch4\CarServerTypeInfo\VB Client: клиент на Visual Basic;
… \Ch4\ CarServerTypeInfo\VJ Client: клиент на J++;
… \Ch4\ CarServerTypeInfo\CPP Import Client: клиент
C++ с библиотекой типов.
В этой работе расширяется сервер CarInProcServer.dll (см. практическое занятие №6) для поддержки информации о типе. Сначала откройте рабочее пространство CarInprocServer (или сделайте копию проекта) и вставьте в проект новый файл (через меню File | New...) с именем CarServerTypeInfo.idl. В этом файле будут находиться все определения интерфейсов, коклассов и библиотек сервера.
48