| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: ActiveX/СОМ/CORBA > Проблемы с локальным COM сервером |
| Автор: Гость_Сергей 4.11.2004, 15:48 |
| Здравствуйте. Я вынужден просить помощь, т.к. сам уже запарился искать решение. Я пытаюсь написать ЛОКАЛЬНЫЙ COM-сервер. Описываю класс объекта на базе TComObject, без библиотеки типов и, соответственно, без флажка OleAutomation. Я надеюсь, что сделать это можно. Все интерфейсы объекта - наследники IUnknown (Custom Iterfaces). В конце модуля, как полагается стоит: initialization TComObjectFactory.Create(ComServer, TUrbOPC, Class_UrbOPC, 'OPCTest', Class_UrbOPC_Descr, ciMultiInstance, tmApartment); end. Проблема возникает, когда пытаюсь в клиенте получить фабрику класса. CoGetClassObject возвращает ошибку CO_E_SERVER_EXEC_FAILURE ($80080005). Прокси для всех интерфейсов объекта зарегистрированы - проверял OleView.exe. На компьютере установлены другие локальные сервера с такой же функциональностью, т.е. имеют те же интерфейсы и подобные объекты, и при этом прекрасно запускаются и работают. Думал, что надо создавать библиотеку типов, хотя клиент имеет описания всех интерфейсов. Потом обнаружил, что некоторые сервера и без библиотеки типов (тоже смотрел в OleView) работают. Файл сервера регистрируется в реестре и находится правильно. Если в секции инициализации написать: initialization TComObjectFactory.Create(ComServer, TUrbOPC, Class_UrbOPC, 'OPCTest', Class_UrbOPC_Descr, ciMultiInstance, tmApartment); ShowMessage('Object Factory Registered'); end. , то при вызове в клиенте CoGetClassObject появится сначала сообщение, а потом выше описанная ошибка. В чем же может быть проблема? Мучаюсь уже недели две, наверно. Заранее спасибо |
| Автор: Гость_Сергей 5.11.2004, 15:37 |
| Ну неужели никто не знает? Хотя бы где копать? Кно нибудь еще встречался с этим? Может быть единственное решение - использовать библиотеку типов? |
| Автор: Fantasist 5.11.2004, 21:26 |
| Ошибка весьма неконткретная, означает что SCM не смог получить объект сервера. Причины могут быть разные. Вывод мессаджа еще ничего не означает. Например, в секции инициализации более поздно инициализируемого модуля может выскакивать исключение, которое приводит к краху запуска. Опять же могу посоветовать в ручную проверить соотвествие GUID-ов IDL с реестром. Это может быть и какая-нибудь глупая ошибка, типа перемещение более новой версии проекта в другое место, а в реестре прописан путь к старой. Если есть возможность выслать проект или выложить куда-нибудь, я посмотрю. |
| Автор: Сергей_SU 6.11.2004, 13:33 |
| Спасибо за ответ. Я выслал вам копию кода и необходимые прокси. Заранее спасибо. PS: Извиняюсь за вопрос, но что такое SCM. Я почему-то не встречался с таким понятием во время своего долгого изучения COM. |
| Автор: Fantasist 6.11.2004, 19:43 | ||
SCM - это Service Control Manager, в данном случае отвественный за связывание указателя на интерфейс с экземпляром объекта. CoGetClassObject - это обращение к SCM. Он будет пытаться загрузить объект и прокси, если необходимо. Вот например: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnesscom/html/usingscm.asp |
| Автор: Fantasist 8.11.2004, 23:51 | ||
Посмотрел. Не запускается цикл выборки сообщений, соответсвенно сервер закрывается сразу после инициализации и запрос на создание объекта никогда не обрабатывается. Предлагаю заменить строчку Application.Run следующим кодом:
P.S. К сожалению дома сейчас Делфи нет, так что пришлось ждать рабочего дня. |
| Автор: Сергей_SU 9.11.2004, 17:51 |
| Огромное спасибо!!! Сегодня или завтра обязательно попробую. Однако ж это вызывает удивление - почему Delphi сама так не делает? Всяких wizard'ов наделали, а вот здесь приходиться ручками. Причем проблема не такая уж и явная, я лично сам вряд ли бы догадался. Кстати, если не сложно, как Вы нашли ошибку? Или просто на базе своих знаний сразу определили проблему? Еще раз спасибо!!!! |
| Автор: Fantasist 9.11.2004, 20:16 | ||||
На мой взгляд, Делфи, не смотря на многие достоинства, не очень оптимизированна под создание некоторых вещей. Например такого визарда как создание COM local server я там не нашел. То есть добавление сервера происходит к основному проекту, который, как считает Делфи, укладывается в основную логику. Основная логика в Делфи, как известно, это приложение центром которого является форма и компоненты к ней.
Запустил проект - закрывается сразу. Поставил бряк, запустил - оказываеться закрывается прямо в Application.Initialize. Удивился, прошелся по нутрям этого метода - дошло что в параметре запуска стоит /regserver. Убрал параметр. Запустил... Закрывается сразу. Но уже после выполнения Application.Run. Залез внутрь Run - очевидно, что не запускаеться цикл, потому что нет основной формы. Создал форму - все запустилось и работает, клиент способен создать сервер, только лишняя форма мелькает. Ну а дальше понятно. Вот теперь есть соответсвующие знания, а значит в следующий раз сразу пойму в чем дело. Делфи я редко использую для создания COM серверов, то есть опыта у меня в этом не так много. P.S. То, что цикл выборки сообщений нужен, и то что в Делфи он обычно запускаеться вызовом Application.Run, факт, думаю, общеизвестный. |
| Автор: Сергей_SU 11.11.2004, 12:15 |
| Все ОК!!!!!!!! Вы мне очень помогли. Еще раз спасибо! PS: идея добавить форму - просто класс. Жаль , что сам не догадался, а ведь действительно локальный COM сервер создаеться в дельфях внутри приложения, где, как думает делфи, должна быть форма. |