Для студентов згиа специальности 080403 ”Программное обеспечение




НазваниеДля студентов згиа специальности 080403 ”Программное обеспечение
страница10/34
Дата публикации25.02.2013
Размер3.71 Mb.
ТипМетодическое пособие
uchebilka.ru > Информатика > Методическое пособие
1   ...   6   7   8   9   10   11   12   13   ...   34

^ Oбщие концепции и требования, предъявляемые к PE-файлам

Структурно PE-файл состоит из заголовка (header), страничного имиджа (image page) и необязательного оверлея (overlay). Представление PE-файла в памяти называется его виртуальным образом (virtual image) или просто образом, а на диске – файлом или дисковым образом. Если не оговорено обратное, то под образом всегда понимается виртуальный образ [23].

Образ характеризуется двумя фундаментальными характеристиками – адресом базовой загрузки (image base) и размером (image size). При наличии перемещаемой информации (relocation/fixup table) образ может быть загружен по адресу, отличному от image base и назначаемому непосредственно самой операционной системой.

Для работы с PE-файлами используются три различных схемы адресации: физические адреса (называемые также сырыми указателями или смещениями raw pointers/raw offset или просто offset), отсчитываемые от начала файла; виртуальные адреса (virtual address или сокращенное VA), отсчитываемые от начала адресного пространства процесса и относительные виртуальные адреса (relative virtual address или сокращенно RVA), отсчитываемые от базового адреса загрузки. Все три измеряются в байтах и хранятся в 32-битных указателях.

Страничный имидж состоит из одной или нескольких секций (кода, данных, импорта и т.д.). С каждой секцией связанs атрибуты: физический адрес начала секции в файле, размер секции в файле, виртуальный адрес секции в памяти, размер секции в памяти и атрибут характеристик секции, описывающий права доступа, особенности ее обработки системным загрузчиком и т.д. Все секции совершенно равноправны и тип каждой из них тесно связан с ее атрибутами.

Оверлей относится к хвостовой части файла, не загружаемой в память.

^ Структура PE-файла

Табл.2.9 Схематическое изображение PE-файла

MS-DOS MZ Header

MS-DOS Real-Mode Stub Program

PE File Signature

PE File Header

PE File Optional Header

.text Section Header

.bss Section Header

.rdata Section Header

. . .

.debug Section Header

.text Section

.bss Section

.rdata Section

. . .

.debug Section

Все PE-файлы без исключения (и системные драйвера в том числе) начинаются с old-exe заголовка за концом которого следует dos-заглушка (ms-dos real-mode stub program или просто stub), обычно выводящая на терминал сообщение "This program cannot be run in DOS mode".

PE-заголовок, в подавляющем большинстве случаев начинающийся непосредственно за концом old-exe программы, на самом деле может быть расположен в любом месте файла – хоть в середине, хоть в конце, т.к. загрузчик определяет его положение по двойному слову e_lfanew, смещенному на 3Ch байт от начала файла. PE-заголовок представляет собой 18h-байтовую структуру данных, описывающую фундаментальные характеристики файла и содержащую "PE\x0\x0" сигнатуру, по которой файл, собственного говоря, и отождествляется.

Непосредственно за концом PE-заголовка, следует опциональный заголовок, специфицирующий структуру страничного имиджа более детально (базовый адрес загрузки, размер образа, степень выравнивания - все это и многое другое задается именно в нем).

За концом опционального заголовка следует таблица секций.

Начиная с raw offset'а первой секции, указанного в таблице секций, простирается страничный имидж, точнее его упакованный дисковый образ [23].



    1. ^ Основы технологии COM

      1. Основные понятия.

Component Object Model (COM) – это двоичный стандарт, в котором определены способы взаимодействия программных продуктов, написанных на разных языках или работающих на различных платформах [24, 35].

Далее мы остановимся на основах архитектуры операционных систем Win32, позволяющей нам создавать и использовать COM-компоненты в своих программах. Мы остановимся на наиболее важных чертах спецификации COM, а также на том, как зарегистрировать COM-компоненты, чтобы приложения-клиенты могли их находить и использовать их функции.

^ Использование COM-объектов

COM-объекты позволяют создавать приложения в виде набора четко определенных компонентов, взаимодействующих друг с другом. Одним из преимуществ таких объектов является их способность обеспечивать взаимодействие независимо от того, где находится двоичный объект. Существенно также, что приложение способно подключаться к объекту динамически во время выполнения.

Например, приложение, являющееся исполняемым файлом, может подключаться к COM-компоненту, находящемуся в DLL. А поскольку такая операция происходит динамически, то им не обязательно находиться в одном месте. В процессе нахождения и подключения двоичного объекта программа работает совместно с операционной системой. В COM определены все элементы, совместно используемые программой и операционной системой для обеспечения корректной работы динамического приложения.

На Рис. 2.3 показаны элементы, участвующие в этом процессе.



Рис. 2.3 COM-элементы, используемые для поддержки динамического подключения

COM-объекты могут находиться как в DLL-, так и в EXE-файлах. Каждый из них в обязательном порядке должен быть зарегистрирован в операционной системе Windows. Сведения о регистрации хранятся в системном реестре, там же находится ClassID – уникальный в глобальном масштабе идентификатор класса в особом формате. Его еще называют GUID.

При создании динамического подключения клиент идентифицирует зарегистрированный двоичный COM-объект по его ClassID. Библиотеки COM времени исполнения представляют собой неотъемлемую часть операционной системы Windows и позволяют клиентам находить и создавать объекты классов COM.

Получив ClassID, библиотеки COM просматривают основной раздел реестра HKEY_CLASSES_ROOT в поисках соответствующего COM-объекта. Найдя его, они создают его экземпляр и возвращают указатель на интерфейс объекта. Клиент использует этот указатель для вызова методов объекта.

Одна из особенностей COM – прозрачность местонахождения (location transparency). При создании приложений-клиентов нас не интересует, где работают используемые нами объекты – в нашем процессе или в каком-то другом, на этом или на удаленном компьютере.

      1. ^ Интерфейсы COM

Услуги Вашего COM-объекта доступны через один или несколько интерфейсов. Интерфейс COM – это множество логически взаимосвязанных методов. Для его идентификации служит GUID, именуемый идентификатором интерфейса (Interface Identifier, IID). Компоненты COM часто описываются в терминах модели «клиент-сервер», в котором COM-сервер – это компонент, предоставляющий свои услуги (методы) клиентским программам. В соответствии с этой моделью интерфейс является описанием услуг, предоставляемых компонентом.

Доступ к предоставляемым интерфейсом методам Вы получаете через указатель на интерфейс, который содержит ссылку на vtable, таблицу указателей на функции, каждый из которых позволяет обратиться к отдельному методу интерфейса.



Рис. 2.4 Компоненты и интерфейсы

На Рис. 2.4 показан COM-сервер Encoder, предоставляющий три интерфейса. Iunknown (его мы обсудим позже) – обязательный интерфейс любого COM-компонента. Интерфейсы Iencode и Icommunicate созданы для предоставления услуг объекта Encoder. Рис. 2.4 иллюстрирует нотацию, принятую по умолчанию для описания COM-компонентов. Методы, предоставляемые интерфейсами, показаны слева от диаграммы.

На Рис. 2.4 видно, что у компонентов и интерфейсов GUID различаются. Показанные здесь GUID – всего лишь идентификаторы, задаваемые в коде препроцессорной директивы #define для обращения к различным типам GUID. Как вы узнаете позже, GUID – это большие шестнадцатеричные числа.

Интерфейс логически отделен от компонента, который его предоставляет, то есть один и тот же интерфейс иногда предоставляет целое множество различных компонентов. Интерфейс похож на определение абстрактного класса в С++. Уникальность интерфейса обеспечивается уникальностью его IID. Выпустив собственную спецификацию интерфейса, Вы тем самым гарантируете любому его пользователю, что изменяться он не будет. Номера и порядок методов, так же как и типы параметров и возвращаемых значений, обязательно останутся теми же. Желая добавить или изменить методы, Вы обязаны определить новый интерфейс с другим IID.

Интерфейс IUnknown

Интерфейс IUnknown, показанный на Рис. 2.5, должен присутствовать в любом COM-компоненте.



Рис. 2.5 Интерфейс IUnknown

IUnknown содержит три метода, реализуемых Вами при создании COM-объекта. В методе QueryInterface() Вы обеспечиваете клиентской программе механизм доступа к любому из интерфейсов, предоставляемых Вашим объектом.

Поскольку один экземпляр компонента может одновременно обслуживать запросы нескольких клиентов, Вы должны создать в своем объекте счетчик использования. Этот закрытый элемент данных отслеживает число подключившихся клиентских приложений. Его обслуживают методы AddRef() и Release(). При обнулении значения счетчика компонент самоуничтожается.

При создании COM-компонентов методы IUnknown должны быть указаны первыми в таблице vtable. Остальные методы, предоставляемые другими интерфейсами, перечисляются за ними.

На Рис.2.6 показан примерный вид таблицы vtable объекта Encoder.



Рис. 2.6 Примерная структура таблицы vtable

В vtable сначала перечислены методы IUnknown, за ними следуют методы, предоставляемые интерфейсом IEncode, а в конце – ICommunicate. Создавая экземпляр объекта Encoder, библиотека COM получает указатель на начало vtable (На Рис. 2.6 – это pVtbl). Он может использоваться для вызова QueryInterface() – первой функции в таблице, которая должна быть организована так, чтобы она возвращала указатель на запрашиваемый интерфейс.

      1. ^ Глобально уникальные идентификаторы

GUID – это 128-разрядные числовые идентификаторы, указывающие на COM-объекты и предоставляемые ими интерфейсы. Они гарантированно уникальны в глобальном масштабе и останутся таковыми достаточно долго. Для генерации GUID своих компонентов и интерфейсов можно использовать утилиту GUIDGEN.EXE или функции Win32 API.

Детальное строение GUID показано на Рис. 2.7.



Рис 2.7 Строение GUID

Известны два вида представления GUID – строковый и числовой. Строковый формат применяется в системном реестре. Числовое представление GUID требуется при использовании в клиентских приложениях и при реализации COM-объекта.

Работая с числовым представлением в COM-объекте или в коде клиента на C++, нужно объявить переменную и инициализировать ее макросом, который носит имя DEFINE_GUID и находится в заголовочном файле initguid.h. Как правило, имя переменной GUID имеет приставку CLSID или IID, что позволяет отличить GUID COM-объекта от глобального идентификатора интерфейса.
^ Элементы реестра, относящиеся к COM

Устанавливая COM-объект на компьютере, Вы обязаны зарегистрировать его в системном реестре. На Рис. 2.8 показаны записи, создаваемые при такой регистрации.



Рис. 2.8 Регистрация COM-объекта

Записи при регистрации размещаются в HKEY_CLASSES_ROOT в подразделе CLSID. Именно сюда обращаются библиотеки при попытке найти и загрузить COM-объект. В разделе CLSID создается подраздел с именем, являющимся строковой формой CLSID объекта, который также в свою очередь должен содержать подраздел, предоставляющий сведения о сервере компонентов. Все это проиллюстрировано ниже:

HKEY_CLASSES_ROOT\CLSID\{64CE33A0-6B03-11D3-9352-0080C7FA0C3E}\

InprocServer32 = c:\Encoder\debug\Encoder.dll

Имя подраздела, InprocServer32, информирует, что серверный компонент – это библиотека DLL, находящаяся на локальной машине.

На один уровень ниже HKEY_CLASSES_ROOT Вы можете поместить раздел со строковым именем своего СОМ-объекта, которое не будет зависеть от версии программным идентификатором (ProgID). Создайте в нем подраздел CLSID с параметром, содержащим значение GUID Вашего объекта в строковом формате. Путь такой записи выглядит примерно так:

HKEY_CLASSES_ROOT\Encoder\CLSID = {64CE33A0-6B03-11d3-9352-0080C7FA0C3E}

Средствами функции CLSIDFromProgID() клиентское приложение может извлечь CLSID из ProgID. Предоставляя ProgID, Вы облегчаете «жизнь» разработчику клиентского приложения, создающему экземпляр Вашего СОМ-объекта: избавляете его от необходимости вручную вводить в исходный текст CLSID — а при этом избежать ошибки довольно трудно. В исходном тексте клиентского приложения на Visual Basic СОМ-объекты всегда определяются по их ProgID, поэтому всегда регистрируйте ProgID, если планируете работу Ваших объектов с другими клиентами (не на С++).


      1. ^ Создание объектов с помощью CoCreateInstance()

Получив CLSID с помощью функции CLSIDFromProgID(), клиент передает его в библиотеку СОМ для загрузки объекта и получения указателя на интерфейс. Для этого служит функция CoCreateInstance(). Используя CLSID и реестр, CoCreateInstance() находит указанный объект, создает его экземпляр и возвращает указатель на его интерфейс.

Вот как выглядит описание CoCreateInstance():

STDAPI CoCreateInstance (REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID * ppv);

Первый параметр — это CLSID объекта. Второй параметр используется для агрегации (aggregation) объекта в качестве части другого объекта.

В третьем параметре задается контекст исполнения объекта. Вот допустимые значения для этого параметра:

CLSCTX_INPROC_SERVER

CLSCTX_INPROC_HANDLER

CLSCTX_LOCAL_SERVER

CLSCTX_REMOTE_SERVER

Параметр riid — это IID запрашиваемого интерфейса. В параметре ppv будет возвращен указатель на интерфейс, но только после успешного создания СОМ-объекта и при условии, что он поддерживает запрошенный клиентом интерфейс.

Детальный порядок операций при создании СОМ-объекта функцией CoCreateInstance() показан на рис. 2.9.



Рис. 2.9 Порядок создания объкта COM

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

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

Библиотека СОМ просматривает соответствующие разделы реестра, пытаясь получить путь и имя компонента-сервера (в данном случае это DLL).

После инициализации сервера создается экземпляр фабрики классов — объекта, способного создавать объекты определенного класса, реализованного в качестве части СОМ-компонента. Фабрика классов предоставляет интерфейс IClassFactory. После этого указатель на интерфейс фабрики класса возвращается обратно в библиотеку СОМ, которая с его помощью запускает метод фабрики Createlnstance(). Созданная Вами версия этого метода создает экземпляр СОМ-класса, который и предоставляет все методы, доступные клиентам, а также таблицу vtable, чтобы клиентское приложение могло пользоваться этими методами. Указатель на интерфейс IUnknown возвращается в библиотеку СОМ, которая, получив его, освобождает объект фабрики классов и передает указатель на IUnknown в клиентское приложение. Теперь он указывает на компонент vtable, позволяя клиенту запускать методы СОМ-объекта.

Вся описанная выше последовательность операций с объектами выполняется только при первичной инициализации СОМ-объекта. Если методы этого объекта понадобятся еще одному клиенту, он получит указатель на интерфейс этого же СОМ-объекта, а сервер увеличит счетчик использования, вызвав IUnknown: :AddRef(). Закончив работу с интерфейсом, клиент обязан вызвать метод IUnknown:: Release() для уменьшения счетчика. Если какой-то из клиентов забудет это сделать, счетчик никогда не обнулится и интерфейс не будет удален, что может вызвать серьезные утечки памяти.

Резюме

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

      1. Маршалинг.

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

Передача данных через границы процесса называется маршалингом (marshaling). Здесь мы рассмотрим способы маршалинга — то, как СОМ-компоненты передают и получают данные методов предоставляемых ими интерфейсов.

СОМ-компонент выполняет одну из трех ролей: сервера, встраиваемого в процесс (in-process server), внешнего сервера (сервер за пределами данного процесса — out-of-process server) или удаленного сервера (remote server).

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

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

Внешний СОМ-объект можно реализовать так, что он будет выполняться на другой машине. Такой объект называется удаленным сервером (remote Server). В этом случае обмен данными между серверным и клиентским компьютерами происходит по сети. Характерное время оклика на запросы методов у такого сервера существенно больше, причем этот показатель может быть нестабильным: время запуска метода (даже если это один и то же метод) значительно варьируется. В перегруженной сети клиентское приложение будет ждать ответа дольше. Код, создаваемый для маршалинга параметров метода в локальный сервер, вполне годится для их передачи и на удаленный сервер. В случае применения удаленного сервера достаточно иметь всего лишь один его экземпляр, загруженный и зарегистрированный на серверной машине. Он сможет обслужить всех клиентов, нуждающихся в его методах. Наличие только одного сервера существенно облегчает и упрощает процесс его модификации (например, изменение методов).

^ Технологии маршалинга

Вопрос маршалинга данных между клиентом и сервером является ключевым при создании СОМ-объекта или сервера. В зависимости от типа взаимосвязи клиента и сервера выбирается конкретная технология передачи данных по запросам методов между клиентским приложением и СОМ-сервером.

В табл. 2.10 перечислены технологии программирования маршалинга, а также типы маршалинга, типы границ, между которыми переносятся данные, и конкретные способы реализации.

Табл. 2.10 Технологии маршалинга данных для COM-объектов

^ Тип маршалинга

Границы

Способ реализации

Отсутствие маршалинга

DLL

Глобальная адресация

Стандартный маршалинг

Процесс

Язык описания интерфейсов (Interface Definition Language, IDL)

Маршалинг Automation

Язык программирования

Маршаллер Automation

Специальный маршалинг

Процесс

Специальное ПО, протокол

Если СОМ-объект используется в качестве сервера, встраиваемого в процесс, то он размещается в DLL, то есть загружается в пространство процесса клиента, и все вызовы методов и передача данных происходят напрямую (без маршалинга).
^ Стандартный маршалинг

Когда клиент вызывает методы интерфейса СОМ-компонента, находящегося на локальном или удаленном сервере, данные передаются через границы процессов или между узлами сети. Дабы такая передача стала возможной, требуется написать код маршалинга, чтобы клиент и сервер смогли общаться друг с другом. Для этого в Visual С++ существует специальная утилита — MIDL-компилятор, позволяющий создать DLL со стандартным маршалингом между внешним объектом и его клиентом. В стандартном маршалинге интерфейсы задаются на языке описания интерфейсов (Interface Definition Language, IDL) — языке со строгим контролем типов и подобным Visual С++ синтаксисом, позволяющим создавать точные описания интерфейсов.

MIDL компилирует IDL-код и генерирует исходный текст на С для двух компонентов — представителя (ргоху) и заглушки (stub). Представитель подсоединяется к клиентскому приложению, а СОМ-сервер — к заглушке. Этот код компилируется в так называемую DLL представителя/заглушки, используемую в СОМ для обслуживания механизма обмена данными между клиентом и СОМ-сервером через границы процессов или сеть.

^ Использование маршалера Automation

Маршалер Automation — это СОМ-сервер (oleaut32.dll), предоставляющий услуги по маршалингу в СОМ-технологии, известной как Automation (раньше ее называли OLE Automation). Она позволяет взаимодействовать с СОМ-компонентами клиентам, написанным на языках отличных от С++. Маршалер Automation реализован в СОМ-интерфейсе IDispatch (подробнее о нем — на следующем занятии). Чтобы пользоваться им, не требуется создавать диспетчерский интерфейс — достаточно указать, что интерфейсы Вашего компонента используют маршалер Automation, задав их IDL-атрибутом Oleautomation.

Для реализации взаимодействия между различными языками в Automation определен стандартный набор типов данных, которые можно поместить в объединение (union) VARIANT. Пользуясь маршалером Automation, Вы должны употреблять только допустимые в ней типы данных.

Резюме

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

      1. ^ Диспетчерские интерфейсы

Ранее Вы узнали, что диспетчерские интерфейсы используют технологию Automation для обеспечения взаимодействия компонентов, написанных на разных языках программирования.

Здесь мы подробнее рассмотрим то, как используются интерфейс IDispatch и тип данных VARIANT для получения доступа к СОМ-компонентам из языков, отличных от С++. А также о том, как клиенты, написанные на поддерживаемых Microsoft языках, например Visual Basic, обращаются напрямую к интерфейсам компонентов, не прибегая к диспетчерским механизмам.

^ Интерфейс IDispatch

Диспетчерские интерфейсы позволяют клиентским приложениям, написанным на различных языках, обращаться к СОМ-объектам. Давайте, к примеру, рассмотрим язык сценариев типа Microsoft Visual Basic Scripting Edition (VBScript), используемый для создания экземпляров СОМ-компонентов, написанных на С++. В VBScript нет строгого контроля соответствия типов, и многие типы из С++ ему неизвестны. Чтобы клиент на VBScript мог успешно связаться с сервером, Вы обязаны предоставить ему диспетчерский интерфейс (dispatch interface). Для этого достаточно реализовать стандартный СОМ-интерфейс IDispatch.

Иногда требуется создать СОМ-объекты, доступные исключительно клиентам на С++. Например, к этой категории относятся объекты, созданные компанией-разработчиком для внутреннего пользования. В этом случае не придется тратить усилия на реализацию IDispatch. Тем не менее, если Вы хотите, чтобы Ваш объект был доступен из более широкого диапазона языков, Вам придется создать этот интерфейс. Клиенты, написанные на языках, поддерживаемых Microsoft (например Visual Basic), все равно в состоянии применять СОМ-компоненты на С++ без интерфейса IDispatch. Но это возможно при условии, что они используют интерфейсы, обменивающиеся только параметрами, которые поддерживаются Automation. К ним относятся параметры таких типов данных, которые можно упаковать в стандартный формат данных VARIANT — определенный в СОМ тип объединения (подробнее об этом далее).

На рис. 2.10 показано, как можно реализовать интерфейс IDispatch для класса Encoder.



Рис. 2.10 Реализация интерфейса IDispatch

Таблица vtable объекта Encoder содержит указатели на функции, реализованные в IDispatch. Клиентское приложение может запускать метод GetIDsOfNames(), передавая имя метода в виде строки, например "Encode". В методе GetIDsOfNames() создается внутренняя таблица, которая связывает имя каждого метода с числовым диспетчерским идентификатором — он называется Dispatch ID, или DISPID — это просто число; в примере на рис. 2.10 DISPID функции Encode равен 1.

Получив DISPID требуемого метода, для его запуска клиентское приложение вызывает Invoke(). Диспетчерский идентификатор, возвращенный GetIDsOfNames(), передается в качестве параметра при вызове метода Invoke(). Кроме того, в него передаются параметры для вызываемых методов, упакованные в массив переменных типа VARIANT, а также указатель на переменную типа VARIANT, в которую будут помещены значения, возвращаемые вызываемым методом.

Созданная Вами версия Invoke() вызывает нужный метод от имени клиента Automation и должна содержать таблицу для перевода значений DISPID в методы компонента. Кроме того, она отвечает за распаковку параметров из массива VARIANT и их корректную передачу соответствующему методу. Необходимо, чтобы все возвращаемые значения были упакованы в объект, на который указывает VARIANT, для дальнейшей передачи обратно клиенту.

Структура данных VARIANT содержит два поля (если пренебречь зарезервированными). Поле vt описывает тип данных во втором поле. Объединение позволяет во втором поле размещать данные различных типов. Поэтому имя второго поля изменяется в зависимости от значения поля vt. Константы, которыми задается значение поля vt, указаны в соответствующей документации.

Таким образом, использовать структуру данных VARIANT нужно в два приема. Взгляните на такой код:

long lvalue = 555; VARIANT vParam;

VParam.vt = VT_I4; vParam.lVal = lvalue;

В первой строке содержатся сведения о типе данных. В константе VT_I4 объявлено, что во втором элементе находится переменная типа long. Из определения типа VARIANT следует, что при сохранении значения типа long в структуре данных VARIANT второму полю должно быть присвоено имя lVal.

^ Библиотеки типов

Вы, наверное, уже поняли, что диспетчерский механизм — относительно медленный способ обмена данными между сервером и клиентом. Кроме того, упаковка/распаковка параметров в/из переменных VARIANT небезопасна с точки зрения сохранения типа. Высокоэффективные языки разработки типа Visual Basic 6.0 должны обращаться к методам интерфейса напрямую через vtable.

Для этого клиенту Visual Basic необходимо знать номер и типы параметров, ожидаемых методами интерфейса. Эти сведения предоставляются клиенту в библиотеке типов (type library) — двоичном описании параметров и методов интерфейса, а также параметров метода. Библиотеку типов можно рассматривать как откомпилированную, независимую от языка версию заголовочного файла С++.

Среда Visual Basic считывает библиотеку типов и предоставляет описание интерфейса программисту. Тот создает экземпляр компонента, используя синтаксис Visual Basic для прямого доступа к vtable компонента. Сведения, полученные из библиотеки типов, позволяют разработчику передавать в методы интерфейса параметры корректных типов. Таким образом, в Visual Basic обходят диспетчерский механизм и повышают производительность, применив сервер, встраиваемый в процесс.

Библиотека типов описывается с применением IDL. MIDL-компилятор создает файл библиотеки типов с расширением*.tlb, который зачастую компонуется вместе с DLL- или ЕХЕ-сервером СОМ-компонента.

Чтобы клиенты, написанные на языках типа Visual Basic, получили доступ к Вашей библиотеке типов, в реестр необходимо внести некоторые записи, относящиеся к СОМ-объекту. Они позволят библиотеке СОМ найти созданную Вами библиотеку типов.

^ Двойные интерфейсы

Наиболее предпочтительно реализовать диспетчерский интерфейс в виде двойного интерфейса (dual interface). В нем все методы Invoke() доступны напрямую — как записи таблицы vtable. На рис. 2.11 показана возможная реализация двойного интерфейса: адреса методов IEncode одновременно включаются как в vtable, так и в справочную таблицу функции Invoke().



Рис. 2.11 Реализация двойного интерфейса

При наличии двойного интерфейса параметры и методы, предоставляемые ком-понентом, остаются доступными через диспетчерский интерфейс с помощью языков типа VBScript, а языки типа С++ могут обращаться к ним напрямую через vtable. В Visual Basic доступны как диспетчерский интерфейс, так и vtable. Двойной интерфейс позволяет клиентам, способным обращаться к vtable, быстрее запрашивать методы, при этом он еще и поддерживает клиентов, нуждающихся в диспетчерском интерфейсе.

Резюме

Интерфейс IDispatch дает возможность клиенту, написанному на языке типа VB-Script, использовать СОМ-объект через общую точку входа — метод InvokeQ. Передаваемые ему параметры упаковываются в структуру данных типа VARIANT, состоящую из двух полей: одно — для описания типа данных и второе — собственно для хранения этих данных.

Библиотека типов служит для того, чтобы среда разработки типа Visual Basic имела возможность создать интерфейс программирования Вашего СОМ-объекта. Библиотека типов — это двоичный файл с описанием методов, параметров и используемых типов данных СОМ-объекта. Visual Basic может применять информацию из этой библиотеки при прямых вызовах методов через указатели на функции, полученные из таблицы vtable СОМ-компонента.

Двойной интерфейс предоставляет параметры и методы компонента как через диспетчерский интерфейс, так и через vtable, в зависимости от возможностей клиента.


    1. ^ Работа с реестром

Реестр – это централизованная иерархическая база данных конфигурации приложений и системы. Доступ к реестру осуществляется через разделы реестра, которые аналогичны каталогам файловой системы. Раздел может содержать другие разделы или пары «параметр–значение», которые можно уподобить именам файлов и их содержимому [3, 15].

Пользователь или администратор могут просматривать и редактировать содержимое реестра с помощью редактора реестра, который вызывается командой REGEDIT. Кроме того, программы могут управлять реестром через функции API.

Точками входа в реестр служат несколько стандартных разделов (root keys):

  • HKEY_LOCAL_MACHINE хранит физическую информацию о машине, а также данные об установленном программном обеспечении.

  • HKEY_USERS содержит данные конфигурации пользователей.

  • HKEY_CURRENT_CONFIG содержит текущие параметры настройки, такие как разрешающая способность монитора и шрифты.

  • HKEY_CLASSES_ROOT содержит подразделы, определяющие соответствие между расширениями файлов и классами и приложениями, используемыми оболочкой для доступа к объектам с этими расширениями. В этом разделе также записаны все данные, необходимые для объектной модели компонентов Microsoft (COM)/

  • HKEY_CURRENT_USER. Сюда относится информация данного пользователя, включая переменные окружения, принтеры и пользовательские настройки приложений.

В этих разделах могут содержаться другие вложенные разделы (subkeys) и параметры. Важно заметить, что в отличие от обычных разделов корневые разделы удалять нельзя. В каждом разделе реестра храниться безымянный параметр обозначаемый в regedit.exe как (По умолчанию). Собственно сама информация храниться в параметрах реестра. Параметры могут быть различных типов, которые перечислены в таблице 2.11.

Табл. 2.11. Типы параметров реестра

Тип

Описание

REG_BINARY

REG_DWORD

REG_EXPAND_SZ

REG_MULTI_SZ

REG_SZ

REG_LINK

REG_DWORD_BIG_ENDIAN

 

REG_DWORD_LITTLE_ENDIAN

 REG_NONE 

Двоичные данные произвольной длины

32-битное число

Строка переменной длины

Массив строк

Текстовая строка фиксированной длины

Символьная ссылка

32-битное число, в котором первым является старший байт. Эквивалентно REG_DWORD.

32-битное число, в котором первым является младший байт. Эквивалентно REG_DWORD.

Нетипизированный параметр

В большинстве случаев используются первые пять типов. Все строковые параметры хранятся в Unicode-формате. В этом формате каждый символ кодируется двумя байтами. Служебным типом данных является тип REG_LINK, который позволяет создавать символические ссылки на другие параметры или разделы.

Вот более подробное описание корневых разделов:

1   ...   6   7   8   9   10   11   12   13   ...   34

Похожие:

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания к лабораторному практикуму для студентов згиа...
Методические указания к лабораторному практикуму для студентов згиа специальности 080403 «Программное обеспечение автоматизированных...

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания для студентов специальности 080403
Згиа [8, 10] и других вузов [4]. Наиболее полно описаны курсовые, дипломные и квалификационные работы, однако большинство положений...

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания к курсовой работе по дисциплине «Системное...
Методические указания к курсовой работе по дисциплине «Системное программирование и операционные системы» для студентов специальности...

Для студентов згиа специальности 080403 ”Программное обеспечение iconПравила использования программного обеспечения в рамках программы...
Используя программное обеспечение вы тем самым подтверждаете свое согласие придерживаться этих правил. Если вы не согласны, не используйте...

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания по выполнению лабораторных работ по курсу “
Информационные управляющие системы и технологии, 080403 – Программное обеспечение автоматизированных систем

Для студентов згиа специальности 080403 ”Программное обеспечение iconКлассификация программного обеспечения
В отличие от аппаратного обеспечения, программы, которые выполняются на нем, неосязаемы и классифицируются как программное обеспечение....

Для студентов згиа специальности 080403 ”Программное обеспечение iconКурсовая работа выполняется на основании 'Задания на курсовую работу'...
Целью курсовой работы является закрепление практических навыков самостоятельной постановки и решения задачи обработки данных с помощью...

Для студентов згиа специальности 080403 ”Программное обеспечение icon1. Классификация программного обеспечения
Назначением ЭВМ является выполнение программ. Программа содержит команды, определяющие порядок действии компьютера. Совокупность...

Для студентов згиа специальности 080403 ”Программное обеспечение iconОпорный конспект лекций по дисциплине Компьютерная графика для специальности...
Тема. Основные понятия компьютерной графики. Аппаратное и программное обеспечение

Для студентов згиа специальности 080403 ”Программное обеспечение iconМетодические указания и задание к выполнению курсового проекта по...
Методические указания и задание к выполнению курсового проекта по дисциплине «Алгоритмическое и программное обеспечение электротехнических...

Вы можете разместить ссылку на наш сайт:
Школьные материалы


При копировании материала укажите ссылку © 2013
контакты
uchebilka.ru
Главная страница


<