Когда речь заходит о разработке компонентов COM в среде Delphi, важно понимать, как корректно обрабатывать ошибки при создании объектов. Вопрос, поставленный пользователем, касается именно этой проблемы: при возникновении ошибок в процессе создания COM-объектов с использованием TComObjectFactory возникают проблемы, связанные с отображением диалоговых окон с ошибками и возможным сбоем клиентского приложения.
Описание Проблемы
Разработчик столкнулся с проблемой при работе с TComObjectFactory в Delphi. При возникновении исключения в методе CreateComObject, предназначенном для создания COM-объектов, клиентское приложение может получить сообщение об ошибке с текстом "DAX Error", что может привести к его сбою. Это происходит из-за неправильного способа отмены создания объекта, когда в случае исключения выводится диалоговое окно с ошибкой.
Контекст
В коде, предоставленном разработчиком, используется событие FStartupCompleteEvent для ожидания готовности приложения перед первым подключением и состояние Provider.State для отключения клиентских подключений при выключении сервера. Однако, при возникновении исключения EAbort.Create('Server shut down.'), возникает описанная проблема.
Подтвержденный Ответ
В соответствии с рекомендациями, не следует допускать возникновения исключений в точке входа COM DllGetClassObject. Вместо этого следует перехватить исключение и вернуть соответствующий код ошибки HResult, например, E_UNEXPECTED. Также упоминается альтернативный подход: изменение метода CreateComObject таким образом, чтобы он возвращал nil, в случае чего DllGetClassObject из ComServ вернет CLASS_E_CLASSNOTAVAILABLE.
Альтернативный Ответ
Возвращение nil из метода CreateComObject является предпочтительным способом индикации ошибки. Это не приведет к сбою RTL при попытке получения интерфейса объекта, как было упомянуто в комментариях, и позволит клиентскому приложению корректно обработать ситуацию.
Пример Кода
function DllGetClassObject(const CLSID, IID: TGUID; var Obj): HResult;
begin
try
Result := ComServ.DllGetClassObject(CLSID, IID, Obj);
except
Pointer(Obj) := nil;
Result := E_UNEXPECTED;
end;
end;
function TPsOPCProviderClientFactory.CreateComObject(const Controller: IUnknown): TComObject;
begin
FStartupCompleteEvent.WaitFor(INFINITE);
if Provider.State = OPC_STATUS_SUSPENDED then
begin
Pointer(Result) := nil;
Exit;
end;
Result := inherited CreateComObject(Controller);
(Result as TPsOPCProviderClient).Provider := Provider;
end;
Заключение
При работе с COM-объектами в Delphi важно правильно обрабатывать ошибки, чтобы избежать нежелательного поведения клиентских приложений. Возврат nil из метода CreateComObject является одним из способов корректной обработки ошибок, не приводящих к сбоям и диалоговым окнам с ошибками. Это позволяет клиентскому приложению адекватно реагировать на ситуацию, когда создание COM-объекта не может быть выполнено.
Обратите внимание, что данный ответ написан с учетом информации, предоставленной в контексте, и предполагает, что разработчик использует версию Delphi, начиная с Delphi 5, что делает информацию актуальной для широкого круга пользователей.
Разработчик сталкивается с проблемами в обработке ошибок при создании COM-объектов в Delphi с использованием TComObjectFactory, что может приводить к сбою клиентского приложения и отображению окна с ошибкой 'DAX Error'.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.