Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Деревянко_БС ЭВМ

.pdf
Скачиваний:
66
Добавлен:
31.05.2015
Размер:
3.6 Mб
Скачать

Если требуется только один экземпляр кокласса, то можно использовать метод СоCreateInstance(). Метод СоCreateInstance() находит объект класса и автоматически вызывает CreateInstance() из указателя IСlassFactory. От программиста требуется передать нужные CLSID и IID. При использовании СоCreateInstance() объект каждый раз создаётся и каждый раз удаляется.

1.2.6. Язык определения интерфейса MIDL

MIDL – (Microsoft Interface Definition Language) яв-

ляется расширением существующего IDL для поддержки СОМ.

Описание СОМ-сервера помещается в файл *.idl и обрабатывается компилятором midl.exe. Использование MIDL обеспечивает языковую независимость и прозрачность местонахождения сервера. Файл *.idl создаётся в среде Visual C++ и автоматически компилируется при сборке проекта.

Основные типы данных IDL (см. табл. 1.1) похожи на их аналоги в языке С. Это язык определений. В нём отсутствуют циклы и условные операторы.

31

 

Таблица 1.1

 

Ключевые слова MIDL

Ключевое

Описание

слово

 

 

 

typedef

Аналогично слову typedef языка С.

 

 

import

Вносит существующие IDL-определения в

 

IDL-файл. Аналогично директиве #include

 

языка С. Пример:

 

import “ouidl.idl” // включает ин-

 

терфейсы автоматизации.

 

 

object

Определяет, что далее следуют определения,

 

относящиеся к СОМ.

 

 

interface

Объявление нового СОМ-интерфейса.

 

 

cpp-quote

Вставка строки в программу на С\С++, гене-

 

рируемую компилятором MIDL (это строка -

 

комментарий).

 

 

uuid

Универсальный уникальный идентификатор

 

(то же, что и GUID).

 

 

helpstring

Вставка строки комментария.

 

 

enum,

Создание перечисления, vl_enum означает 32-

vl_enum

битные перечисления

 

 

library

Оператор библиотеки типов с обязательным

 

атрибутом uuid определяет, какие коклассы

 

содержатся в сервере (ЕХЕ или DLL - библио-

 

теке).

 

 

importlib

Импорт в откомпилированную библиотеку.

 

Должна, как минимум, импортироваться

 

стандартная библиотека типов stdole32.tlb.

 

 

32

 

Продолжение табл. 1.1

Ключевое

Описание

слово

 

 

 

[in]

Атрибут параметра метода, передаваемого от

 

клиента к серверу (параметр, задаваемый по

 

умолчанию).

 

 

[out]

Атрибут параметра метода, передаваемого от

 

сервера к клиенту.

 

Клиент освобождает память полученных дан-

 

ных. Параметр [out] – это всегда указатель.

 

 

[in, out]

Посылка от клиента к серверу. Клиент отво-

 

дит и освобождает память, но сервер тоже

 

может управлять памятью при вызове метода.

 

 

coclass

Объявление кокласса в библиотеке, uuid –

 

обязателен.

 

 

default

Определение интерфейса по умолчанию.

 

Каждый кокласс должен иметь ровно один

 

интерфейс по умолчанию. Используется для

 

работы с С\С++.

 

 

Пример определения интерфейсов сервера CarServer средствами IDL.

import “oaidl.idl”

 

...

 

// ICreateCar

 

[object, uuid (...),

// IID

helpstring (“Create a car”)]

 

interface ICreateCar: IUnknown

 

{

 

33

HRESULT SetPetName ([in] BSTR petName);

HRESULT SetMaxSpeed ([in] int maxSp);

};

[uuid (...), //LIBID helpstring (“CoCar Server with TypeLib”)] library CarServer

{

importlib(“stdole32.tlb”); //должна

быть //первой строкой в

библиотеке

[uuid (...)]

//CLSID

coclass CoCar

 

{

 

[default] interface ICreateCar; interface IStats;

interface IEngine;

};

};

Файлы, генерируемые компилятором MIDL

Имена большинства генерируемых MIDL-файлов основаны на первоначальном имени IDL-файла. Для файла CarServer.idl, например, строятся следующие файлы.

CarServer.h – содержит определение интерфейса с использованием интерфейсных макросов СОМ.

CarServer_i.c – содержит все определения GUID. Для каждого атрибута [uuid] формируется соответствующая константа с префиксом IID_ , CLSID_ или

LIBID_.

CarServer.tlb – двоичный эквивалент текста IDL, который называется библиотекой типов. Важно, что программы и на других языках, кроме С\С++, могут ис-

34

пользовать содержащиеся в них коклассы, интерфейсы и пользовательские типы.

CarServer_p.c и dlldata.c – используются для формирования dll, содержащего заглушки/прокси для удалённого доступа к СОМ-интерфейсам.

Для того чтобы другие языки могли получить информацию о типе сервера, надо ввести информацию о файле *.tlb в системный реестр под ключом

HKEY_CLASSES_ROOT/TypeLib.

1.3.Технология DCOM

1.3.1.Организация обмена между клиентом

исервером (маршалинг)

В модели СОМ одна и та же программа пользователя используется для доступа к СОМ-объекту независимо от его физического расположения. СОМ создает иллюзию, что все вызовы методов интерфейсов происходят внутри процесса. Для этого во время выполнения используется DLL, содержащая объекты «заглушка» и «прокси».

Процедура обмена между клиентом и локальным или удаленным сервером посредством использования заглушек и прокси называется маршалингом. Коды заглушек и прокси генерируются для всех определенных на IDL интерфейсов. Маршалинг осуществляется с помощью механизма удаленного вызова процедур (RPC).

Заглушка-объект – это СОМ-объект, загруженный в процесс сервера, который получает запросы клиента и передает реальному объекту.

Прокси-объект – это СОМ-объект, загруженный в процесс клиента, который отправляет запросы клиента к методам интерфейсов. Это СОМ-объект, поддерживающий

35

стандартные СОМ-интерфейсы. Прокси располагаются внутри процесса клиента и предоставляют клиенту локальные или удаленные интерфейсы.

Следующий посредник на пути между клиентом и сервером – объект канала ORPC (Object RPC). Объект канала поддерживает интерфейс IRpcChannelBuffer. Этот интерфейс разбивает на пакеты запросы клиента и посылает их заглушке, используя вызовы RPC низкого уровня.

Прокси поддерживает интерфейс IRpcProxyBuffer. Этот интерфейс используется для установления или разрыва связи между прокси-объектом и объектом канала. IRpcProxyBuffer содержит два метода:

Connect() и Disconnect(). Метод Connect() в

качестве параметра принимает указатель интерфейса

IRpcChannelBuffer.

Связь между клиентом, прокси и объектом канала иллюстрирует рис. 1.7.

36

Пространство процесса клиента

IRpcProxyBuffer

Клиент,

 

имеющий

IDraw

pDraw

 

 

IDraw

 

IRpcChannelBuffer

 

Канал к CoHexa-

 

gon Draw

 

IUnknown

 

Передача запроса заглушке ин-

 

терфейса IDraw кокласса CoHex-

 

agon c помощью ORPC

Рис. 1.7. Связь между клиентом, прокси

 

и объектом канала

Прокси-объекты поддерживают IRpcProxyBuffer, позволяющий им связываться с объектом канала. На серверной стороне объект-заглушка реализует стандартный СОМ-интерфейс IRpcStubBuffer, который аналогично интерфейсу IRpcProxyBuffer тоже поддерживает методы Connect() и Disconnect(). Запрос, полу-

ченный от объекта канала ORPC, направляется заглушкой серверу (см. рис. 1.8) .

Схема вызова метода удаленного интерфейса показана на рис. 1.9.

37

 

Пространство процесса сервера

Менеджер

 

IUnknown

IUnknown

IDra

 

IDrawStub

 

IRpcStubBuffer

 

IUnknown

CoHexagon

IShapeEditStub

 

IRpcStubBuffer

IShapeEdit

 

 

Реализация CoHexagon::Draw()

Рис. 1.8. Заглушки реализуют IrpcStubBuffer для распаковки запроса и передают

его реальному СОМ-объекту

38

Клиент

 

 

IUnknow

 

 

 

 

pDraw

IRpcProxyBuffer

 

IDrawStub

 

 

 

 

IDraw

IDrawProxy

IRpcStubBuffe

 

 

 

r

IUnknow

 

 

 

IRpcChannelBuffe

Канал к IDraw

CoHexago

кокласса CoHex

n

 

 

 

 

 

 

 

 

 

IDraw

 

Рис. 1.9. Схема вызова метода удалённого интерфейса

39

Объекты прокси и заглушки – это обычные объекты СОМ, которые создаются одной фабрикой класса с интерфейсом IPSFactoryBuffer. Как только клиент запрашивает доступ к удаленному интерфейсу, соответствующие менедже-

ры вызывают метод CreateProxy() или CreateStub() ин-

терфейса IPSFactoryBuffer. Далее прокси и заглушка загружаются в процессы клиента и сервера.

В процессе установки пограммы-сервера, то есть всем коклассам, присутствующим в исполняемом файле, присваивается идентификатор приложения AppID (GUID).

Все зарегистрированные в системном реестре СОМприложения перечисляются под ключом HKCR/AppID. Там же могут содержаться именованные значения, касающиеся параметров защиты конкретного приложения, например, список пользователей, которым разрешен доступ к серверу, уровень аутентификации и т.п.

Чтобы избежать недостатков внутрипроцессного СОМобъекта, то есть запустить внутрипроцессный СОМ-сервер в режиме локального сервера, применяется утилита dllhost.exe, строящая суррогатный процесс. В этом случае DLL на основе СОМ загружается с характеристиками отдельного процесса. Чтобы внутрипроцессный сервер загрузился в оболочку dllhost.exe, а не в процесс клиента, требуется внести необходимые записи в реестр системы.

Кроме того, надо перекомпилировать клиент с флагом

CLSCTX_LOCAL_SERVER в методе CoGetClassObject().

1.3.2. Виды маршалинга в модели СОМ

Имеется три основных способа обмена информацией между процессами.

1. Пользовательский маршалинг. Реализуется стандартный интерфейс IMarshal, не используется ORPC, программист самостоятельно разрабатывает программы обмена. Это сложный способ обмена.

40

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]