Текущий архив: 2004.07.18;
Скачать: CL | DM;
Вниз
try ... finally Найти похожие ветки
← →
Анонимщик © (2004-07-01 17:41) [0]Как можно определить:
try
finally
// мы сюда попали нормальным образом или где-то после try было
// сгенерировано исключение?
end
← →
Sandman25 © (2004-07-01 17:41) [1]Normal := False;
try
...
Normal := True;
finally
// мы сюда попали нормальным образом или где-то после try было
// сгенерировано исключение?
if Normal then
...
end
← →
Петров Денис © (2004-07-01 18:12) [2]> Анонимщик © (01.07.04 17:41)
Зачем?
← →
Анонимщик © (2004-07-01 18:16) [3]Петров Денис
А что?
← →
Ega23 © (2004-07-01 18:17) [4]try
try
......
except
......
end;
finally
.....
end;
← →
Iconka © (2004-07-01 18:17) [5]Потому что.
← →
Анонимщик © (2004-07-01 18:19) [6]Sandman25
Не подходит. Я пытаюсь избежать локальной раскрутки. Есть AbnormalTermination, но нигде в исходниках дельфи не нашел ее. Даже не знаю, в какой dll она реализована
← →
Петров Денис © (2004-07-01 18:21) [7]Анонимщик © (01.07.04 18:16) [3]
Зачем определять в блоке finally...end, было исключение или нет? Ведь в нем должны располагаться действия, выполняемые ВНЕЗАВИСИМОСТИ от того, было исключение, или нет.
Например, ты открыл файл, поработал с ним и в блоке try...finally
Какая разница, возникло исключение или нет? Ты же все равно должен будешь его закрыть.
> Ega23 © (01.07.04 18:17) [4]
Остроумно.
← →
GuAV © (2004-07-01 18:22) [8]
> Остроумно
Что остроумного? так же и есть.
← →
Анонимщик © (2004-07-01 18:22) [9]Петров Денис
Слушай, не понимаешь ничего, так не лезь
← →
Петров Денис © (2004-07-01 18:30) [10]> Анонимщик © (01.07.04 18:22) [9]
Хам.
> GuAV © (01.07.04 18:22) [8]
Как это поможет определить в блоке finally-end, было ли исключение, если оно будет обработанов во вложенном блоке try-except?
← →
Ega23 © (2004-07-01 18:34) [11]Как это поможет определить в блоке finally-end, было ли исключение, если оно будет обработанов во вложенном блоке try-except?
Проверь следующий код:
procedure TForm1.Button2Click(Sender: TObject);
var
i:TList;
begin
try
try
i.Clear;
except on E:Exception do
ShowMessage("Except");
end;
finally
ShowMessage("Finally");
end;
end;
← →
GuAV © (2004-07-01 18:36) [12]
> если оно будет обработанов
А если тамraise;
то оно будет поднято снова.
← →
TUser © (2004-07-01 18:40) [13]Да уж, дискуссия ...
← →
Петров Денис © (2004-07-01 18:41) [14]> Ega23 © (01.07.04 18:34) [11]
> GuAV © (01.07.04 18:36) [12]
Жестоко. Тогда уж
Sandman25 © (01.07.04 17:41) [1]
форева.
Вопрос в том, нафига? Просто по-человечески интересно, когда такое может понадобиться?
← →
Анонимщик © (2004-07-01 18:45) [15]Я же сказал, для воспрепятствования локальной раскрутки
← →
Ega23 © (2004-07-01 18:47) [16]Жестоко.
В смысле?
← →
Анонимщик © (2004-07-01 18:56) [17]Ладно, кому интересно, почитайте
http://asterra.by.ru/library/richter4ru/head23.htm
до AbnormalTermination и скажите, если есть соображения.
← →
Петров Денис © (2004-07-01 19:05) [18]> Анонимщик © (01.07.04 18:45) [15]
Интересно. Раскрутка - это попытка выхода из защищенного блока до его окончания, так?
Попробую привести пример, хотя он лучше смотрится на C...
Раскрутка:
function f: integer;
begin
EnterCriticalSection(cs);
try
...
// здесь код, потенциально вызывающий исключение
...
Result := 0;
Exit; // вот здесь будет включен механизм раскрутки
// так как выход из защищенного блока будет произведен
// до его окончания
finally
LeaveCriticalSection(cs);
end;
end;
Нет раскрутки:
function f: integer;
begin
EnterCriticalSection(cs);
try
...
// здесь код, потенциально вызывающий исключение
...
finally
LeaveCriticalSection(cs);
end;
Result := 0;
end;
Так что проблема решается не определением факта генерации исключения в защищенном блоке, а правильным построением логики работы кода. Так?
← →
Плохиш © (2004-07-01 19:15) [19]
> Ega23 © (01.07.04 18:34) [11]
> Проверь следующий код:
А ты проверь следующий код:
procedure TForm1.Button2Click(Sender: TObject);
var
i:TList;
begin
try
i.Clear;
except on E:Exception do
ShowMessage("Except");
end;
ShowMessage("Finally");
end;
← →
GuAV © (2004-07-01 19:29) [20]
> Плохиш © (01.07.04 19:15) [19]
> А ты проверь следующий код:)
> procedure TForm1.Button2Click(Sender: TObject);
> var
> i:TList;
> begin
>
> try
> try
> i.Clear;
> except on E:Exception do
> ShowMessage("Except");
raise;
> end;
> finally
> ShowMessage("Finally");
> end;
> end;
← →
Igorek © (2004-07-01 20:00) [21]
procedure TForm1.Button2Click(Sender: TObject);
var
i:TList;
EA: TObject;
procedure F(CalledByException: Boolean);
begin
// мы сюда попали нормальным образом или где-то после try было
// сгенерировано исключение?
if CalledByException then
end;
begin
try
i.Clear;
//other code
//...
except
F(True);
raise;
end;
F(False);
end;
← →
Анонимщик © (2004-07-02 10:49) [22]Петрову.
Нет, не так.
Ладно, дискуссия закончена, не туда обратился. Всем спасибо.
← →
Digitman © (2004-07-02 11:47) [23]
> Анонимщик © (02.07.04 10:49) [22]
перехват встроенной ф-ции @System.RaiseExcept либо API-ф-ции kernel32.RaiseException дает инф-цию об объекте исключения, адрес объекта доступен в регистре eax в момент передачи управления в точку перехвата
← →
Digitman © (2004-07-02 11:55) [24]
> Анонимщик
псевдокод в качестве иллюстрации возможного решения:
TRaiseException = function(..): ... ; stdcall;
OldRE: TRaiseException;
Obj: TObject;
..
function NewRaiseException(..): ... ; stdcall;
begin
asm
mov [Obj], eax;
end;
Result := OldRE(..);
end;
...
OldRE := GetProcAddress(hKernel, "RaiseException");
SetProcAddress(hKernel, @NewRaiseException);
Obj := nil;
try
Assert(False);
finally
SetProcAddress(hKernel, @OldRE);
if Assigned(Obj) then
begin
Showmessage(Obj.ClassName);
Obj := nil;
end;
...
end;
← →
Тимохов © (2004-07-02 12:01) [25]А что это за функция такая SetProcAddress?
У меня в msnd ее нет.
← →
Digitman © (2004-07-02 12:06) [26]
> Тимохов © (02.07.04 12:01) [25]
сам напиши)
перехват WinAPI-вызовов - избитая тема
← →
Igorek © (2004-07-02 12:33) [27]в unit SysUtils есть:
function ExceptObject: TObject;
function ExceptAddr: Pointer;
Но они работают только в блоке try...except.
Остается только сожалеть:
- что они не работают в блоке try...finally
- что в Дельфи нету блока try...except...finally
← →
Анонимщик © (2004-07-02 12:50) [28]Digitman
Я, собственно, хотел сделать на дельфи то же, что у Рихтера в книге, только и всего. А все мне сказанне не утешает.
← →
Тимохов © (2004-07-02 12:53) [29]
> Digitman © (02.07.04 12:06) [26]
смешно.
я так вообще и понял, что это мета функция.
> Igorek © (02.07.04 12:33) [27]
а если при возникновении исключения воспользуйетесь функцией AcquireExceptionObject, то они будут работать где угодно :))
← →
Digitman © (2004-07-02 13:17) [30]
> Тимохов © (02.07.04 12:53) [29]
> смешно.
ну уж не смешней твоего вопроса, мол, а где это ..
прекрасно же понимаешь, что нет такой ф-ции в WinAPI
← →
Igorek © (2004-07-02 13:37) [31]
> а если при возникновении исключения воспользуйетесь функцией
> AcquireExceptionObject, то они будут работать где угодно
> :))
А что это за функция такая AcquireExceptionObject?
У меня в msnd ее нет.
← →
Тимохов © (2004-07-02 13:56) [32]
> Igorek © (02.07.04 13:37) [31]
модуль system.
> Digitman © (02.07.04 13:17) [30]
забыл смайлы поставить :))
я сначала не прочел комментарий в начале: "это псевдокод".
виноват.
← →
Digitman © (2004-07-02 14:20) [33]
> Тимохов © (02.07.04 13:56) [32]
> не прочел
без вопросов
> Анонимщик © (02.07.04 12:50) [28]
> все мне сказанне не утешает.
эт почему ? таки завелся с пол-пинка - доведи уж дело до конца ... оно мож и не в ту степь едешь, но чрезвычайно полезно для понимания ..
← →
Igorek © (2004-07-02 14:21) [34]
> Тимохов © (02.07.04 13:56) [32]
>
> > Igorek © (02.07.04 13:37) [31]
>
> модуль system.
У меня Д5. Нету такой функции.
Нашел только
function RaiseList: Pointer; { Stack of current exception objects }
Надо будет проверить.
← →
Тимохов © (2004-07-02 14:26) [35]
> Igorek © (02.07.04 14:21) [34]
ставь шестой - там точно есть.
← →
Digitman © (2004-07-02 14:41) [36]
> Igorek © (02.07.04 14:21) [34]
> У меня Д5. Нету такой функции.
> Нашел только
> function RaiseList: Pointer; { Stack of current exception
> objects }
> Надо будет проверить.
даже и не проверяй, не трать время
в теле finally-блока ничего кроме nil ты не увидишь в RaiseList
причем вне зависимости от версии среды
указатель этот неявно устанавливается в не-nil-значение непосредственно перед передачей управления в except-блок
← →
Анонимщик © (2004-07-02 15:04) [37]Digitman
А все и так завелось, но я чего-то, все же, не понимаю. А хотелось разобраться.
Тогда к этому еще один вопрос. Есть статья про критические секции на
http://www.microsoft.com/rus/msdn/magazine/archive/2003-12/CriticalFull.asp
Начал проверять на дельфи, ничего не вышло. Все поля в RTL_CRITICAL_SECTION (поле FSection) равны нулю всегда. Как же все-таки определить, сколько конкурирующих потоков ждут входа?
← →
Digitman © (2004-07-02 15:07) [38]
> Анонимщик © (02.07.04 15:04) [37]
> чего-то, все же, не понимаю. А хотелось разобраться
на то и форум
говори, ЧТО конкретно не понимаешь
← →
Igorek © (2004-07-02 15:20) [39]
> в теле finally-блока ничего кроме nil ты не увидишь в RaiseList
> причем вне зависимости от версии среды
Спасибо.
← →
Анонимщик © (2004-07-02 15:50) [40]Digitman
Начнем с AbnormalTermination. Я хочу написать это слово в pas-модуле так, чтобы компилятор не ругался. Что для этого нужно сделать? Комментирование не предлагать.
Страницы: 1 2 вся ветка
Текущий архив: 2004.07.18;
Скачать: CL | DM;
Память: 0.57 MB
Время: 0.056 c