Исключения и DLL в Delphi - PullRequest
       11

Исключения и DLL в Delphi

4 голосов
/ 12 февраля 2010

Как правильно обрабатывать исключения, генерируемые из DLL в Delphi?

Примерно так

on E : ESomeException do ...

или

if (E is ESomeException) then ...

не удается из-за отдельных реестров типов DLL и основного приложения.

Ответы [ 4 ]

8 голосов
/ 12 февраля 2010

За исключениями чистой DLL не разрешается пересекать границу DLL (как упоминает Deltics ) - независимо от того, на каком языке.

Вы получаете всевозможные проблемы там , особенно потому, что вы не знаете, какой язык, RTL, менеджер памяти и т. Д. Находятся по обе стороны границы.

Итак, вы вернулись к классической парадигме обработки ошибок:

  • коды ошибок (аналогично HResult )
  • сообщения об ошибках (аналогично GetLastError )

Вместо DLL вы можете использовать пакеты BPL (как предложено Lars ): там вы знаете, что обе стороны будут использовать один и тот же RTL и диспетчер памяти.

И пакеты, и BPL обычно все равно дают вам кошмар версионирования (слишком много степеней свободы).

Более строгое решение - использовать монолитный исполняемый файл; это решает обе проблемы:

  • намного более легкая версия
  • гарантированно только один RTL и диспетчер памяти

- Йерун

PS: я сделал это дополнительным ответом, потому что это облегчает вставку ссылок.

5 голосов
/ 12 февраля 2010

Самый безопасный способ - не допустить, чтобы исключения "уходили" из DLL.

Но если у вас нет контроля над источником DLL и, следовательно, вы не можете этого гарантировать, вы все равно можете проверить имя класса исключения:

if SameText(E.ClassName, 'ESomeException') then ...
3 голосов
/ 12 февраля 2010

Если вы используете пакеты времени выполнения (по крайней мере, rtlxx.bpl) как для своего приложения, так и для своей DLL, то оба имеют одинаковый тип, и он будет работать. Конечно, это ограничивает использование вашей DLL только Delphi / BCB.

Другое решение вообще не использует исключения, как предлагает Deltics. Вернуть коды ошибок.

Или используйте COM. Тогда вы можете иметь исключения и не ограничивать свою DLL только Delphi.

0 голосов
/ 12 февраля 2010

Этот обходной путь, кажется, делает это для меня:

 function ExceptionMatch (Exc : Exception; ExcClass : TClass) : Boolean;

 var
    CurrClass           : TClass;

  begin
  CurrClass := Exc.ClassType;
  while (CurrClass <> nil) do
    begin
    if SameText (CurrClass.ClassName, ExcClass.ClassName) then
      Exit (True);
    CurrClass := CurrClass.ClassParent;
    end;
  Result := False;
  end;

Я готов, чтобы ты это уничтожил :)

Что не так с этим подходом? Что потенциально опасно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...