Форум: "Потрепаться";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];
ВнизException vs ErrorCode Найти похожие ветки
← →
Aldor_ (2005-02-04 21:11) [0]Допустим имеем модуль с набором процедур\функций\классов. Юнит живет самостоятельно, "из него только торчат методы" (c)
Возникает вопрос: что использовать в ситуации, когда функция\метод не может выполнится корректно (например, fool-proof fail) - raise Exception или специальное возвращаемое значение (как в WinAPI) и устроить GetLastError местного значения (в пределах юнита)?.
Чем руководствоваться при принятии такого решения?
← →
Гаврила © (2005-02-04 21:33) [1]От ситуации.
Если тебе снаружи придется после каждого вызова одной и той же функции проверять результат, то есть писать один и тот же код проверки по 10 раз, то лучше исключение внутри функции
Если функция возвращает значение, и его нельзя отличить от ошибки выполнения, тоже самое.
Иногда имеет смысл сделать 2 функции
первая возвращает результат, свидетельствующий об ошибке,
вторая вызывает первую и поднимает исключение, если надо. Снаружи вызываешь ту ,которая в данном случае удобнее
← →
вредитель (2005-02-04 21:47) [2]ИМХО.
Использование подобия GetLastError с классами частично нарушает инкапсуляцию. Когда классы начинают разрастаться, то имеют стремление разбегаться по отдельным модулям. Т.о. либо в каждом модуле необходимо заводить свою переменную, содержащую код ошибки, либо делать глобальную переменную для программы. В первом случае, если имеются неск. модулей, непонятно, какая ошибка была действительно последней (необх. учитывать все ошибки), во втором случае нарушается инкапсуляция, что не есть хорошо и даже есть плохо. По этому, на мой взгляд, лучше использовать исключения.
← →
Alexander Panov © (2005-02-04 21:50) [3]Для работы с DLL намного проще использовать коды ошибок, а все Exception обрабатывать внутри DLL.
Для обычных функций - как удобнее в каждом конкретном случае.
← →
Игорь Шевченко © (2005-02-04 22:07) [4]Alexander Panov © (04.02.05 21:50) [3]
> Для работы с DLL намного проще использовать коды ошибок
Если не используется ShareMem, то это вообще единственный способ :)
С уважением,
← →
Набережных С. © (2005-02-04 22:33) [5]>вредитель (04.02.05 21:47) [2]
А зачем подобие? Почему бы ее и не использовать.
>Aldor_ (04.02.05 21:11)
ИМХО, вопрос не простой. Нужно оценивать степень информативности обоих способов, а также возможную область применения. Возбуждение исключения влечет немалые накладные расходы, причем самого дорогого ресурса - процессорного времени, в некоторых случаях это может оказаться критичным. Неплохо дать возможность принимать решение тому, кто будет использовать этот модуль. По-моему, в подобных вещах исключения нужно возбуждать только в действительно критичных и маловероятных случаях, например, при неправильных параметрах или некорректном использовании класса. Утрированно говоря, не стоит поднимать исключение, если пользователь нажал отмену в диалоге:) Хотя, конечно, это не догма и возможны разные вариации. Все ИМХО, разумеется.
← →
Alex Konshin © (2005-02-04 22:36) [6]Игорь Шевченко © (04.02.05 22:07) [4]
Alexander Panov © (04.02.05 21:50) [3]
> Для работы с DLL намного проще использовать коды ошибок
Если не используется ShareMem, то это вообще единственный способ :)
Это почему же? Никто не говорит, что исключение обязательно должно быть объектом класса-наследника SysUtils.Exception. Оно может быть и не объектом вовсе. Другое дело, что в Delphi с такими исключениями работать неудобно, вполне возможно, что приложение просто рухнет. Вообще-то я как-то пытался использовать неException объекты в качестве параметра raise. Я не помню результат, но по-моему работало.
← →
Shaman_Naydak (2005-02-04 22:48) [7]+ копеечка к высказыванию Alex Konshin..
Что не надо стыдиться использовать пакеты, они для того и придуманы ;)
← →
Набережных С. © (2005-02-04 22:51) [8]>Alex Konshin © (04.02.05 22:36) [6]
>я как-то пытался использовать неException объекты в качестве параметра raise
Вполне работает. Но без сервиса SysUtils, правда, и это решаемо.
← →
Aldor_ (2005-02-04 23:22) [9]Игорь Шевченко © (04.02.05 22:07) [4]
Если не используется ShareMem, то это вообще единственный способ :)
Из-за того, что в Exception.Create передается string или из-за чего-то еще?
вредитель (04.02.05 21:47) [2]
Использование подобия GetLastError с классами частично нарушает инкапсуляцию. Когда классы начинают разрастаться...
Было в голове такое решение: каждый класс имеет свой FLastErrorCode и, соответственно, свой GetLastError. А для функций модуля - общий инкапсулированный внутри модуля LastError.
Для однопоточной программы даже при наличии нескольких таких модулей все ОК. Right?
зависит от конкретного случая
Вот например в случае написания библиотеки "на экспорт" есть общепринятые соглашения?
P.S. Дельфийский механизм try\finally\except работает на основе виндового SEH?
← →
Игорь Шевченко © (2005-02-04 23:41) [10]
> P.S. Дельфийский механизм try\finally\except работает на
> основе виндового SEH?
Конечно.
Alex Konshin © (04.02.05 22:36) [6]
> Это почему же? Никто не говорит, что исключение обязательно
> должно быть объектом класса-наследника SysUtils.Exception.
> Оно может быть и не объектом вовсе
В случае, когда оно не является объектом, тогда, весьма вероятно, и можно передавать исключения из сферы влияния одного Memory Manager"а в сферу влияния другого.
Однако, help гласит:
"To raise an exception, call the reserved word raise, followed by an instance of an exception object. This allows you to establish an exception as coming from a particular address. When an exception handler actually handles the exception, it finishes by destroying the exception instance, so you never need to do that yourself."
Кстати, а пример можно ? :)
С уважением,
← →
Aldor_ (2005-02-04 23:43) [11]
Игорь Шевченко © (04.02.05 23:41) [10]
> P.S. Дельфийский механизм try\finally\except работает на
> основе виндового SEH?
Конечно.
Так значит можно исключения, порождаемые дельфийским кодом обрабатывать в коде C++? (только опять встает вопрос о ShareMem и DLL)
← →
GuAV © (2005-02-06 17:54) [12]Кстати, такой вот вопрос, если у меня известно что приложение не Delphi, можно ли выпускать исключения (которые объекты) из dll ?
Очевидно что сообщение исключения не будет показано. Будет ли memory leak объекта exeption ? Можно ли вообще предполагать что приложение готово корректно обработать исключение ?
← →
Набережных С. © (2005-02-06 18:52) [13]>GuAV © (06.02.05 17:54) [12]
Объекты - нет.
Демо пример возбуждения исключений в длл и обработке в хосте лежит здесь:
http://kladovka.com.ru/index.php?action=view&filename=ExceptTestGroup.zip&directory=Programs&PHPSESSID=9846be0cd6b1c3a7f e2d7baa6ca310ff
Без ShareMem и пакетов:) Такое сключение можно принять и сишной программе, если она их коды.
← →
kaZaNoVa © (2005-02-06 19:01) [14]<offtopic>
Набережных С. © (06.02.05 18:52) [13]
спасибо за использования Кладовки, проблему с русскими буквами постараюсь разрешить в самое ближайшее время)
</offtopic>
← →
Набережных С. © (2005-02-06 19:02) [15]Последнюю вразу читайте пожалуйста так:)
Такое исключение можно принять и в сишной программе, если она знает его код.
← →
y-soft © (2005-02-06 19:03) [16]>GuAV © (06.02.05 17:54) [12]
Можно ли вообще предполагать что приложение готово корректно обработать исключение ?
Нет, некоторые среды разработки не поддерживают SEH. В прочем, системный обработчик Windows исключение все равно не минует (только придется довольствоваться пресловутым "Программа выполнила недопустимую операцию и будет закрыта" :) )
Кстати, ошибки при обработке исключений как раз наиболее вероятны, когда Dll и хост-программа написаны на Delphi, но в разных версиях (не дай Бог, TObject определен по разному :( )...
Позволю себе усомниться в некоторых ранее высказанных мнениях. Смею утверждать, что если обрабатывать в программе на Delphi исключения, возникшие в Dll, корректно (т.е. гарантированно не производить в хост-приложении перераcпределения памяти, выделенной в Dll), то даже ShareMem не нужен. Для иллюстрации выложил простенький тестовый проект, который показывает некоторые закономерности:
http://y-soft.comsignal.ru/Delphi/ExceptionTest.zip
P.S. Я сам предпочитаю подход, высказанный Alexander Panov © (04.02.05 21:50) [3], но совсем по иным причинам...
P.P.S. Поосторожнее с подходом, примененным в "улучшенном" варианте обработки в примере. В некоторых случаях он может быть потенциально опасен...
P.P.P.S. Я уже давненько не участвовал в подобных дискуссиях на форуме, успел поотвыкнуть от нравов :) Так что прошу соблюдать культуру ведения дискуссии. Если я в чем-то неправ, то сразу же после аргументированных доводов это признаю :)
← →
Набережных С. © (2005-02-06 19:03) [17]>kaZaNoVa © (06.02.05 19:01) [14]
Да, я получил письмо, спасибо.
← →
Набережных С. © (2005-02-06 19:06) [18]>y-soft © (06.02.05 19:03) [16]
Забавно получилось:)
← →
y-soft © (2005-02-06 19:11) [19]>Набережных С. © (06.02.05 19:06) [18]
Это о сообщении длиной 65535 байт, или о подходе?
← →
Набережных С. © (2005-02-06 19:15) [20]>y-soft © (06.02.05 19:11) [19]
Да нет конечно! О том, как мы практиски одновременно с примерами:)
← →
Набережных С. © (2005-02-06 19:16) [21]>y-soft © (06.02.05 19:11) [19]
Я твое и посмотреть не успел. Щас гляну, че там строка:)
← →
y-soft © (2005-02-06 19:17) [22]>Набережных С. © (06.02.05 19:15) [20]
Понял :)
Это все из-за того, что раньше форум не работал...
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.034 c