Навигация
Главная
Поиск
Форум
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
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Содержание сайт... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Создание отчето... 63898
Модуль Forms 63632
ТЕХНОЛОГИИ ДОСТ... 60477
Пример работы с... 59845
Имитационное мо... 55944
Реклама
http://altair-lc.ru/ перевозка негабаритных бытовок манипулятором.
Сейчас на сайте
Гостей: 13
На сайте нет зарегистрированных пользователей

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

Моделирование работы обрабатывающего участка цеха в GPSS
Метод конечных разностей для интерполяции/экстраполяции на Delphi
База данных электронного документооборота на Delphi + бд Intebase

Реклама



Подписывайся на YouTube канал о программировании, что бы не пропустить новые видео!

ПОДПИСЫВАЙСЯ на канал о программировании
Моникеры и сохраняемость



Обсуждение моникеров не может быть полным без обсуждения файлового моникера ( File Moniker ). Напомним, что СОМ предусматривает три примитива активации: привязывание к объектам класса, привязывание к новым экземплярам класса и привязывание к постоянным объектам, хранящимся в файлах. В данной главе детально анализировались первые два из этих примитивов. Третий примитив основан на API-функции СОМ CoGetInstanceFromFile :
HRESULT CoGetInstanceFromFile( [in, unique] COSERVERINFO *pcsi,
// host/security info – информация о хосте/безопасности
[in, unique] CLSID *pClsid,
// explicit CLSID (opt) – явный CLSID (opt)
[in, unique] IUnknown *punk0uter,
// for aggregation – для агрегирования
[in] DWORD dwClsCtx,
// locality? – локализация?
[in] DWORD grfMode,
// file open mode – режим открытия файла
[in] OLECHAR *pwszName,
// file name of object – файловое имя объекта
[in] DWORD cmqi,
// how many interfaces? – сколько интерфейсов?
[out, size_is(cmqi)] MULTI_QI *prgmq
// where to put itfs – куда поместить интерфейсы
);



Эта функция принимает на вход имя файла, которое относится к постоянному состоянию ( persistent state ) объекта [1] . CoGetInstanceFromFile удостоверяется в том, что объект исполняется, после чего возвращает один или несколько интерфейсных указателей на (ре)активированный объект. Чтобы выполнить эту работу, CoGetInstanceFromFile в первую очередь требуется определить CLSID данного объекта. CLSID требуется по двум причинам. Если объект не исполняется, то CLSID необходим СОМ для создания нового экземпляра, который будет инициализирован от постоянного (находящегося в файле) образа. Во-вторых, если вызывающий объект не указывает определенное хост-имя до запроса на активацию, то СОМ будет использовать CLSID для выяснения того, на какой машине следует активировать объект [2] .
Если CLSID не передается явно вызывающим объектом, то CoGetInstanceFromFile извлекает CLSID из самого файла с помощью вызова API-функции СОМ GetClassFile :
HRESULT GetClassFile([in, string) OLECHAR *pwszFileName, [out] CLSID *pclsid);
Для определения типа объекта, содержащегося в файле, GetClassFile использует информацию из заголовка файла, а также информацию из реестра.
После того как определены класс и хост-машина, СОМ исследует ROT (Running Object Table – таблица исполняющихся объектов) на целевой хост-машине для того, чтобы выяснить, является ли объект уже активированным. Таблица ROT является инструментом SCM, который преобразует произвольные моникеры в экземпляры объектов, исполняющихся на локальной хост-машине. Ожидается, что постоянные объекты будут регистрировать себя в локальной ROT во время загрузки. Чтобы представить файловое имя постоянного объекта в качестве моникера, СОМ предусматривает стандартный тип моникера – файловый моникер, который оборачивает имя файла в интерфейс IMoniker . Файловые моникеры могут создаваться либо путем передачи файлового имени в МkParseDisplayName , либо вызовом явной API-функции CreateFileMoniker :
HRESULT CreateFileMoniker( [in, string] const OLECHAR *pszFileName, [out] IMoniker **ppmk);
Если постоянный объект уже зарегистрировал в ROT свой файловый моникер, то CoGetInstanceFromFile просто возвращает указатель на уже работающий объект. Если же объект в ROT не найден, то СОМ создает новый экземпляр файлового класса и инициализирует его из постоянного объекта с помощью метода IPersistFile::Load этого экземпляра:
[object, uuid(0000010b-0000-0000-C000-000000000046)]
interface IPersistFile : IPersist
{
// called by CoGetInstanceFromFile to initialize object
// вызывается функцией CoGetInstanceFromFile для
// инициализации объекта
HRESULT Load(
[in, string] const OLECHAR * pszFileName, [in] DWORD grfMode
);
// remaining methods deleted for clarity // остальные методы удалены для ясности
}



Реализация объекта отвечает за загрузку из файла всех постоянных элементов и за саморегистрацию в локальной таблице ROT – с целью убедиться, что для каждого файла в каждый момент может исполняться только один экземпляр:
STDMETHODIMP::Load(const OLECHAR *pszFileName, DWORD grfMode)
{
// read in persisted object state
// считываем сохраненное состояние объекта
HRESULT hr = this->MyReadStateFromFile(pszFile, grfMode);
if (FAILED(hr)) return hr;
// get pointer to ROT from SCM
// берем указатель на ROT от SCM
IRunningObjectTable *prot = 0;
hr = GetRunningObjectTable(0, &prot);
if (SUCCEEDED(hr))
{
// create a file moniker to register in ROT
// создаем файловый моникер для регистрации в ROT
IMoniker *pmk = 0;
hr = CreateFileMoniker(pszFileName, &pmk);
if (SUCCEEDED(hr))
{
// register self in ROT
// саморегистрация в ROT
hr = prot->Register(0, this, pmk, &m_dwReg);
pmk->Release();
}
prot->Release();
}
return hr;
}



Метод IPersistFile::Load нового созданного экземпляра будет вызван диспетчером SCM во время выполнения CoGetInstanceFromFile . В приведенном выше примере для получения указателя на интерфейс IRunningObjectTable в SCM используется API-функция СОМ GetRunningObjectTable . Этот интерфейс затем используется для регистрации своего моникера в ROT, так что последующие вызовы CoGetInstanceFromFile , использующие то же файловое имя, не будут создавать новые объекты, а вместо этого возвратят ссылки на этот объект [3] .
Существование File Moniker обусловлено двумя причинами. Во-первых, он нужен, чтобы позволить объектам самим регистрироваться в ROT, чтобы их мог найти CoGetInstanceFromFile . Во-вторых, чтобы скрыть от клиента использование CoGetInstanceFromFile за интерфейсом IMoniker . Реализация File Moniker из BindToObject просто вызывает CoGetInstanceFromFile :
// pseudo-code from OLE32.DLL // псевдокод из OLE32.DLL
STDMETHODIMP FileMoniker::BindToObject(IBindCtx *pbc,
IMoniker *pmkToLeft,
REFIID riid, void **ppv) {
// assume failure – на случай сбоя
*ppv = О;
HRESULT hr = E_FAIL;
if (pmkToLeft == 0) {
// no moniker to left – слева моникеров нет
MULTI_QI mqi = { &riid, 0, 0 };
COSERVERINFO *pcsi;
DWORD grfMode;
DWORD dwClsCtx;
// these three parameters are attributes of the BindCtx
// эти три параметра являются атрибутами BindCtx
this->MyGetFromBindCtx(pbc, &pcsi, &grfMode, &dwClsCtx);
hr = CoGetInstanceFromFile(pcsi, 0, 0, dwClsCtx,
grfMode, this->m_pszFileName,
1, &mqi);
if (SUCCEEDED(hr))
*ppv = mqi.pItf;
} else {
// there's a moniker to the left – слева есть моникер
// ask object to left for IClassActivator
// or IClassFactory
// запрашиваем объект слева от IClassActivator или от
// IClassFactory
}
return hr; }



При таком поведении File Moniker следующая функция, вызывающая CoGetInstanceFromFile
HRESULT GetCornelius(IApe * &rpApe)
{
OLECHAR *pwszObject = OLESTR(\\\\server\\public\\cornelius.chmp);
MULTI_QI mqi = { &IID_IApe, 0, 0 };
HRESULT hr = CoGetInstanceFromFile(0, 0, 0, CLSCTX_SERVER, STCM_READWRITE, pwszObject, 1, &mqi);
if (SUCCEEDED(hr)) rpApe = mqi.pItf;
else rpApe = 0;
return hr;
}
может быть упрощена, если вместо этого использовать вызов CoGetObject :
HRESULT GetCornelius(IApe * &rpApe)
{
OLECHAR *pwszObject = OLESTR(\\\\server\\public\\cornelius.chmp);
return CoGetObject(pwszObject, 0, IID_IApe, (void**)&rpApe);
}



Как и в предыдущем случае, когда использовался Class Moniker , уровень изоляции, обеспеченный CoGetObject , позволяет клиенту задавать сколь угодно сложную стратегию активации, не меняя ни единой строки кода.
Опубликовал Kest July 13 2009 14:14:00 · 0 Комментариев · 6407 Прочтений · Для печати

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


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



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

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

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

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

Пароль



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

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

Случайные загрузки
С/C++ Программиро...
DS_Group
Библия для програ...
Ранги для форума
Черный круг двига...
Работа с матрицами
Шифрование по алг...
Программирование ...
Факториал [Исходн...
Электронный магаз...
INSTANT BOOSTER v...
Trojan [Исходник ...
C# в кратком изло...
Drag&Drop
MiniTetris [Исход...
Просмотр коммент...
Matrix2D
Редактор анимаций
Усложнённый кальк...
NetGraph [Исходни...

Топ загрузок
Приложение Клие... 100449
Delphi 7 Enterp... 85813
Converter AMR<-... 20067
GPSS World Stud... 12518
Borland C++Buil... 11575
Borland Delphi ... 8504
Turbo Pascal fo... 7023
Visual Studio 2... 4989
Калькулятор [Ис... 4739
FreeSMS v1.3.1 3536
Случайные статьи
Целочисленный арг...
Дополнение телепро...
Все идентификаторы...
Использование клас...
Адаптер для указат...
Работа с MySQL. Де...
Фаза управления
Local object types...
Абстрактные типы д...
Изменение значений...
Пример создания по...
Эмуляция карты NFC
Идея регулярных вы...
Программа Stufflt ...
Сайты компаний
Разработать прикл...
Мануал по созданию...
Implementation exp...
Язык С: проверка т...
установки)300 клие...
Использование новы...
Стандартные исключ...
Заключение
Функции-операции п...
Назначение физичес...
Статистика



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


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