Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 8
На сайте нет зарегистрированных пользователей

Пользователей: 13,372
новичок: vausoz
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Программа тестирования и обучающая программа по математике на Turbo Pasc...
Моделирование круглосуточного интернет кафе на GPSS + Отчет
Лабораторная работа по динамическим спискам на Turbo Pascal (удаление ду...

Совмещение имен в IDL



Часто бывает необходимо объединить традиционные (старые) типы данных и идиомы программирования в одну систему на основе СОМ. В идеале существует простое и очевидное преобразование традиционного кода в его аналог, совместимый с IDL. Если у нас именно такой случай, то тогда переход к СОМ будет достаточно простым. Существуют, однако, ситуации, когда традиционные типы данных или идиомы приложения просто не могут разумным образом преобразовываться в IDL. Для решения этой проблемы в IDL предусмотрено несколько технологий замещения ( aliasing techniques ), которые позволяют разработчику интерфейса составлять подпрограммы преобразования, способные переводить традиционные типы данных и идиомы в легальные, доступные для вызова представления на IDL.
Прекрасным примером ситуации, в которой данная технология полезна, является идиома IEnum . Идиома нумератора СОМ была разработана раньше, чем компилятор IDL, поддерживаемый СОМ. Это означает, что первый разработчик интерфейса IEnum не мог проверить свою разработку на соответствие известным правилам преобразования в IDL. Метод перечислителя Next не может быть чисто преобразован в IDL [1] . Рассмотрим идеальный IDL-прототип метода Next :
HRESULT Next([in] ULONG cElems, [out, size_is(cElems), length_is(*pcFetched)] double *prg, [out] ULONG *pcFetched);



К сожалению, исходное «до-IDL-овское» определение метода Next устанавливало, что вызывающие программы могут передавать в качестве третьего параметра нулевой указатель, при условии, что первый параметр показывал, что запрашивается только один элемент. Это предоставляло вызывающим программам удобную возможность извлекать по одному элементу за раз:
double dblElem;
hr = p->Next(1, &dblElem, 0);



Данное допустимое использование интерфейса противоречит приведенному выше IDL-определению, так как [out] -параметры самого верхнего уровня не имеют права быть нулевыми (нет места, куда интерфейсный заместитель мог бы сохранять результат). Для разрешения этого противоречия каждое определение метода Next должно использовать атрибут [call_as] для замены вызываемой формы ( callable form ) метода его отправляемой формой ( remotable form ).
Атрибут [call_as] позволяет разработчику интерфейса выразить один и тот же метод в двух формах. Вызываемая форма метода должна использовать атрибут [local] для подавления генерирования маршалирующего кода. В этом варианте метода согласовывается, какие клиенты будут вызывать и какие объекты – реализовать. Отправляемая форма метода должна использовать атрибут [call_as] для связывания генерируемого маршалера с соответствующим методом в интерфейсной заглушке. Этот вариант метода описывает отправляемую форму интерфейса и должен использовать стандартные структуры IDL для описания запроса и ответных сообщений, необходимых для отзыва метода. Применяя технологию [call_as] к методу Next , получим такой IDL-код:
interface IEnumDoubIe : IUnknown {
// this method is what the caller and object see
// данный метод, как его видят вызывающая программа и объект
[local] HRESULT Next([in] ULONG cElems,
[out] double *prgElems, [out] ULONG *pcFetched);
// this method is how it goes out on the wire
// данный метод, как он выходит на передачу
[call_as(Next)]
HRESULT RemoteNext([in] ULONG cElems, [out, size_is(cElems), length_is(*pcFetched)] double *prg, [out] ULONG *pcFetched);
HRESULT Skip([in] ULONG cElems);
HRESULT Reset(void); HRESULT Clone([out] IEnumDouble **ppe);
}



Результирующий заголовочный файл C/C++ будет содержать определение интерфейса, включающее в себя метод Next , но не определение метода RemoteNext . Что касается клиента и объекта, то у них нет метода RemoteNext . Он существует только для того, чтобы интерфейсный маршалер мог правильно отправить метод. Хотя у методов Next и RemoteNext списки параметров идентичны, при использовании данной технологии этого не требуется. На самом деле иногда бывает полезно включить в отправляемую форму метода добавочные параметры, чтобы дать исчерпывающее определение тому, как эта операция будет отправлена.
С добавлением в метод пары атрибутов [local]/[call_as] исходный код, сгенерированный интерфейсным маршалером, более не сможет успешно компоноваться из-за непреобразованных внешних символов. Дело в том, что в этом случае разработчик интерфейса должен предусмотреть две дополнительных подпрограммы. Одна из них будет использоваться интерфейсным заместителем для преобразования формы метода с атрибутом [local] в форму с атрибутом [call_as] . B случае приведенного выше определения интерфейса компилятор IDL будет ожидать, что разработчик интерфейса обеспечит его следующей функцией:
HRESULT STDMETHODCALLTYPE IEnumDouble_Next_Proxy(IEnumDouble *This, ULONG cElems, double *prg, ULONG *pcFetched);



Вторая необходимая подпрограмма используется интерфейсной заглушкой для преобразования формы метода с атрибутом [call_as] в форму с атрибутом [local] . В случае приведенного выше определения интерфейса компилятор IDL будет ожидать от разработчика интерфейса следующей функции:
HRESULT STDMETHODCALLTYPE IEnumDouble_Next_Stub(IEnumDouble *This, ULONG cElems, double *prg, ULONG *pcFetched);



Для удобства прототипы для этих двух подпрограмм будут приведены в сгенерированном заголовочном файле C/C++.
Как показано на рис. 7.10, определяемая пользователем подпрограмма [local]-to-[call_as] используется для заполнения таблицы vtbl интерфейсного заместителя и вызывается клиентом. Данная подпрограмма предназначена для преобразования вызова в удаленный вызов процедуры посредством вызова отправляемой версии, которая генерируется компилятором IDL. Для подпрограммы нумератора Next необходимо только убедиться, что в качестве третьего параметра передается ненулевой указатель:
HRESULT STDMETHODCALLTYPE IEnumDouble_Next_Proxy( IEnumDouble *This, ULONG cElems, double *prg, ULONG *pcFetched) {
// enforce semantics on client-side
// осуществляем семантику на стороне клиента
if (pcFetched == 0 && cElems != 1) return E_INVALIDARG;
// provide a location for last [out] param
// обеспечиваем место для последнего [out]-параметра
ULONG cFetched;
if (pcFetched == 0) pcFetched = &cFetched;
// call remote method with non-null pointer as last param
// вызываем удаленный метод с ненулевым указателем
// в качестве последнего параметра
return IEnumDouble_RemoteNext_Proxy(This, cElems, prg, pcFetched);
}



Отметим, что во всех случаях отправляемая версия метода получает в качестве последнего параметра ненулевой указатель.
Определяемая пользователем подпрограмма [local]-to-[call_as] будет вызываться интерфейсной заглушкой после демаршалинга отправляемой формы метода. Эта подпрограмма предназначена для преобразования отправляемой формы вызова в локальный вызов процедуры на текущий объект. Поскольку реализации объекта иногда проявляют небрежность и не считают нужным показывать, сколько элементов возвращается при возвращении S_OK , правильность установки этого параметра обеспечивает подпрограмма преобразования со стороны объекта:
HRESULT STDMETHODCALLTYPE IEnumDouble_Next_Stub( IEnumDouble *This, ULONG cElems, double *prg, ULONG *pcFetched) {
// call method on actual object
// вызываем метод на текущий объект
HRESULT hr = This->Next(cElems, prg, pcFetched);
// enforce semantics on object-side
// проводим в жизнь семантику на стороне объекта
if (hr == S_OK)
// S_OK implies all elements sent
// S_OK означает, что все элементы посланы
*pcFetched = cElems;
// [length_is] must be explicit
// атрибут [length_is] должен быть явным
return hr;
}



Интерфейсная заглушка всегда будет вызывать данную подпрограмму с ненулевым последним параметром.
Технология с атрибутом [call_as] является полезной при организации преобразований из вызываемой формы в отправляемую по схеме «метод-за-методом». В СОМ также предусмотрена возможность специфицировать определяемые пользователем преобразования для отдельных типов данных при помощью атрибутов определения типов [transmit_as] и [wire_marshal] . Эти три технологии не следует считать основными при разработке интерфейсов; они существуют в основном для поддержки традиционных идиом и типов данных. Еще одним приемом, которым владеет компилятор IDL, является cpp_quote. Ключевое слово cpp_quote разрешает появление в IDL-файле любых операторов C/C++, даже если этот оператор не является допустимым в IDL. Рассмотрим следующее простейшее применение cpp_quote для внедрения определения встраиваемой функции в сгенерированный IDL заголовочный файл:
// surfboard.idl
cpp_quote(«static void Exit(void) { ExitProcess(1); }»)



Имея данный IDL-код, сгенерированный C/C++ заголовочный файл будет просто содержать следующий фрагмент:
// surfboard.h static void Exit(void) { ExitProcess(1); }



Ключевое слово cpp_quote может быть использовано для осуществления различных трюков в компиляторе IDL. Примером этого может служить тип данных REFIID . Фактическим определением IDL для этого типа является typedef IID *REFIID;
В то же время тип C++ определен как typedef const IID& REFIID;
Однако ссылки в стиле C++ не допускаются в IDL. Для решения данной проблемы системный IDL-файл использует следующий прием:
// from wtypes.idl (approx.)
// из файла wtypes.idl (приблизительно)
cpp_quote(«#if 0») typedef IID "REFIID;
// this is the pure IDL definition
// это чисто IDL-определение
cpp_quote(«#endif») cpp_quote(«#ifdef _cplusplus») cpp_quote(«#define REFIID const IID&»)
// C++ definition
// определение C++
cpp_quote(«#else») cpp_quote(«#define REFIID const IID * const»)
// С definition
// определение С
cpp_quote(«#endif»)
Результирующий заголовочный файл C++ выглядит так:
// from wtypes.h (approx.)
// из файла wtypes.h (приблизительно)
#if 0 typedef IID *REFIID;
#endif
#ifdef _cplusplus
#define REFIID const IID&
#else
#define REFIID const IID * const
#endif



Этот несколько гротескный прием необходим, поскольку многие базовые интерфейсы СОМ были определены без учета возможного применения IDL.

Асинхронные методы

Вызовы методов в СОМ являются по умолчанию синхронными. Это означает, что клиентский поток заблокирован до тех пор, пока ответное ORPC-сообщение не получено и не демаршалировано. Такая схема в полной мере демонстрирует, как работает обычный вызов метода в одном потоке ( same-thread ), и это с полным основанием принято по умолчанию. До появления Windows NT 5.0 не было способа осуществить вызов метода и продолжать обработку одновременно с выполнением метода без явного порождения дополнительных потоков. В версии СОМ Windows NT 5.0 вводится поддержка асинхронного вызова метода. Асинхронность является свойством метода и должна быть выражена в IDL посредством применения атрибута [async_uuid] .
Детали этой технологии во время написания данного текста находились в процессе непрерывного изменения. За подробностями обращайтесь к соответствующей документации.
Опубликовал Kest July 13 2009 13:43:41 · 0 Комментариев · 9646 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Flud Vkontakte.ru
AJAX и PHP. разра...
Переработанный пл...
JanReplace
FreeSMS v1.3.1
Учебник для продв...
Векторный редакто...
Система баннеро...
Crystal Button
Мод "register.php...
SUIPack
isoCanvas (Редакт...
Введение в станда...
CoolHints2k
VFW
База для Allsubmi...
Cooltray
Язык программиров...
ProLIB18
Delphi и технолог...

Топ загрузок
Приложение Клие... 100793
Delphi 7 Enterp... 98030
Converter AMR<-... 20298
GPSS World Stud... 17060
Borland C++Buil... 14244
Borland Delphi ... 10376
Turbo Pascal fo... 7392
Калькулятор [Ис... 6082
Visual Studio 2... 5232
Microsoft SQL S... 3674
Случайные статьи

Запрограммировать ...
Файлы не подчиняют...
(Request Security)...
Метод экспертного ...
Необходимые типы д...
Точки останова
Азартные игры в Ин...
Структура наследов...
состав группы, соб...
На вход поступает ...
Семантические сети
Модель включения
Применение стилей ...
Обработка вызова в...
Просмотр состояния...
Заглавные и строчн...
Введение в создани...
Мы можем вынести о...
Скачать приложение...
Азартный отдых в к...
Определение процес...
Чехол для планшета...
Указатели на функц...
Pin up - bir yerd&...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?