|
|
|
CreateComObject и фабрика класса
|
|||
|---|---|---|---|
|
#18+
Помогите, пожалуйста, разобраться. Есть проект локального COM-сервера в виде exe-файла. В главном юните проекта где расположен коклас реализующий интерфейс в секции initialization создаётся объект фабрики класса для создания COM-объекта сервера: TComponentFactory.Create(ComServer,имя кокласса,CLSID кокласса,ciSingleInstance,tmFree); На клиенте создание COM-объекта происходит с помощью вызова стандартной функции Delphi CreateComObject из юнита ComObj: CreateComObject(CLSID кокласса); Я не могу понять кто в итоге создаёт COM-объект? Вернее, как именно он создаётся? С использованием этой фабрики класса TComponentFactory или нет? Ну т.е. когда происходит вызов функции CreateComObject, то как то потом неявно вызывается ли метод указанной фабрики класса, который уже в свою очередь создаёт этот COM-объект? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2017, 18:37:40 |
|
||
|
CreateComObject и фабрика класса
|
|||
|---|---|---|---|
|
#18+
Грубое описание. При регистрации сервер добавляет ключ реестра HKEY_CLASSES_ROOT\CLSID\{CLSID}\LocalServer32, где прописан путь до exe файла самого сервера. Когда клиент вызывает CreateComObject(CLSID), то COM система читает из реестра этот путь и запускает exe файл на исполнение и ждет кое-чего (об это ниже). При запуске COM сервер создает фабрику TComponentFactory.Create, сама фабрика внутри себя вызывает CoRegisterClassObject(CLSID). Имеено этого и ждет COM система (если не ошибаюсь, максимум 5 минут). После регистрации происходят вызовы методов зарегистрированной фабрики и создание экземпляра самого сервера. Ссылка на сервер готова, выход из CreateComObject. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.10.2017, 23:08:48 |
|
||
|
CreateComObject и фабрика класса
|
|||
|---|---|---|---|
|
#18+
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. Ведь в зависимости от этого значения будет запущен или отдельный процесс сервера или увеличена ссылка на тот же процесс. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2017, 12:23:08 |
|
||
|
CreateComObject и фабрика класса
|
|||
|---|---|---|---|
|
#18+
Еще одно грубое описание. У 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.10.2017, 14:43:31 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=39530523&tid=2041752]: |
0ms |
get settings: |
8ms |
get forum list: |
21ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
185ms |
get topic data: |
11ms |
get forum data: |
4ms |
get page messages: |
52ms |
get tp. blocked users: |
2ms |
| others: | 240ms |
| total: | 531ms |

| 0 / 0 |
