powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / CreateComObject и фабрика класса
5 сообщений из 5, страница 1 из 1
CreateComObject и фабрика класса
    #39530454
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Помогите, пожалуйста, разобраться.

Есть проект локального COM-сервера в виде exe-файла.
В главном юните проекта где расположен коклас реализующий интерфейс в секции initialization создаётся объект фабрики класса для создания COM-объекта сервера:

TComponentFactory.Create(ComServer,имя кокласса,CLSID кокласса,ciSingleInstance,tmFree);

На клиенте создание COM-объекта происходит с помощью вызова стандартной функции Delphi CreateComObject из юнита ComObj:

CreateComObject(CLSID кокласса);

Я не могу понять кто в итоге создаёт COM-объект? Вернее, как именно он создаётся? С использованием этой фабрики класса
TComponentFactory или нет? Ну т.е. когда происходит вызов функции CreateComObject, то как то потом неявно вызывается ли метод указанной фабрики класса, который уже в свою очередь создаёт этот COM-объект?
...
Рейтинг: 0 / 0
CreateComObject и фабрика класса
    #39530523
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Грубое описание.

При регистрации сервер добавляет ключ реестра HKEY_CLASSES_ROOT\CLSID\{CLSID}\LocalServer32, где прописан путь до exe файла самого сервера. Когда клиент вызывает CreateComObject(CLSID), то COM система читает из реестра этот путь и запускает exe файл на исполнение и ждет кое-чего (об это ниже). При запуске COM сервер создает фабрику TComponentFactory.Create, сама фабрика внутри себя вызывает CoRegisterClassObject(CLSID). Имеено этого и ждет COM система (если не ошибаюсь, максимум 5 минут). После регистрации происходят вызовы методов зарегистрированной фабрики и создание экземпляра самого сервера. Ссылка на сервер готова, выход из CreateComObject.
...
Рейтинг: 0 / 0
CreateComObject и фабрика класса
    #39530686
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AniskinГрубое описание.

При регистрации сервер добавляет ключ реестра HKEY_CLASSES_ROOT\CLSID\{CLSID}\LocalServer32, где прописан путь до exe файла самого сервера. Когда клиент вызывает CreateComObject(CLSID), то COM система читает из реестра этот путь и запускает exe файл на исполнение и ждет кое-чего (об это ниже). При запуске COM сервер создает фабрику TComponentFactory.Create, сама фабрика внутри себя вызывает CoRegisterClassObject(CLSID). Имеено этого и ждет COM система (если не ошибаюсь, максимум 5 минут). После регистрации происходят вызовы методов зарегистрированной фабрики и создание экземпляра самого сервера. Ссылка на сервер готова, выход из CreateComObject.

Огромное спасибо! Теперь всё встало на свои места. Остался единственный непонятный момент:

вот вы пишите, что COM система после вызова клиентом CreateComObject(CLSID) запускает exe файл COM сервера на исполнение по пути указанному в реестре, т.е. получается уже создаётся экземпляр сервера. А потом вы пишите, что после того как фабрика будет создана и зарегистрирована, то будет создан экземпляра самого сервера. Вы имеете ввиду будет создан экземпляр кокласса, т.е. COM-объект? Или всё-таки будет запущен exe-файл COM-сервера в соответствии c указанным в конструкторе фабрики значением параметра Instancing = ciSingleInstance или ciMultiInstance. Ведь в зависимости от этого значения будет запущен или отдельный процесс сервера или увеличена ссылка на тот же процесс.
...
Рейтинг: 0 / 0
CreateComObject и фабрика класса
    #39530788
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Еще одно грубое описание.

У COM системы есть глобальная общая на все процессы таблица, в которой есть 4 поля: CLSID, ссылка на фабрику, флаги фабрики, ссылка на объект. Именно в эту таблицу происходит запись информации при вызове фабрикой функции CoRegisterClassObject. Флаги, которые нас интересуют - REGCLS_SINGLEUSE и REGCLS_MULTIPLEUSE, которые соответствуют ciSingleInstance и ciMultiInstance соответственно.

CreateComObject вызывает CoCreateInstance, которая анализирует эту табличку последовательно перебирая все строки таблицы. Если в в текущей строке таблицы CLSID равен запрашиваемому CLSID, то проверяется ссылка на объект. Если ссылки нет, то вызываются методы фабрики и создается объект сервера, ссылка на объект заносится в таблицу, выход. Если ссылка есть, то анализируются флаги. Если выставлен флаг REGCLS_MULTIPLEUSE, то берется существующая ссылка на объект и происходит выход. Если выставлен флаг REGCLS_SINGLEUSE, то текущая запись таблицы пропускается.

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

Псевдокод:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
function CoCreateInstance(const CLSID: TGUID): IUnknown;
var
  Index: Integer;
begin
  while True do
    begin
      for Index := 0 to GlobalTable.Count - 1 do
        if GlobalTable[Index].CLSID = CLSID then
          if not Assigned(GlobalTable[Index].Obj) then
            begin
              GlobalTable[Index].Obj := GlobalTable[Index].Factory.CreateObj;
              Result := GlobalTable[Index].Obj;
              Exit;
            end
          else
            if GlobalTable[Index].Flags and REGCLS_MULTIPLEUSE <> 0 then
              begin
                Result := GlobalTable[Index].Obj;
                Exit;
              end;

      ReadRegistryAndCreateNewProcess;
      WaitForFactoryRegistration;
    end;
end;

function CoRegisterClassObject(const CLSID: TGUID; AFactory: IUnknown; AFlags: DWORD): Integer;
begin
  Result := GlobalTable.Add(CLSID, AFactory, AFlags);
end;
...
Рейтинг: 0 / 0
CreateComObject и фабрика класса
    #39530842
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aniskin,

теперь всё понятно, ещё раз большое спасибо!
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / CreateComObject и фабрика класса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]