![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
WaitForMultipleObject, Event, ReadDirectoryChangesW, AV
Анонимщик1 © (2007-03-11 23:45:00)Я пытаюсь мониторить изменения в каталоге. Все, вроде бы, выходит, если бы не одно "но". Как только вызов функции оказывается
в блоке try, возникает AccessViolation. Не могу понять, с чем это может быть связано. Не может ли кто растолковать?
Для получения AV достаточно раскомментировать закомментированные строки.
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
FhSpyDir: THandle;
FhDirChangeEvent : THandle;
FSpyBufArray : array[0..4096] of byte;
function InitReadDirCh: boolean;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
const
FILE_LIST_DIRECTORY = $0001;
procedure TForm1.FormCreate(Sender: TObject);
begin
FhDirChangeEvent := CreateEvent(nil, false, false, nil);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
rez : dword;
pStpChgHandles : TWOHandleArray;
i: Integer;
last: Cardinal;
begin
pStpChgHandles[0] := FhDirChangeEvent;
FhSpyDir := CreateFile(PAnsiChar('C:\!TEST!'),
FILE_LIST_DIRECTORY,FILE_SHARE_READ or
FILE_SHARE_DELETE,
nil,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED,
0);
if FhSpyDir = INVALID_HANDLE_VALUE then
Exit;
if InitReadDirCh then
begin
// try
rez := WaitForMultipleObjects(1, @pStpChgHandles, false, INFINITE);
if rez = WAIT_OBJECT_0+1 then
begin
end;
// finally
last := GetLastError;
OutputDebugString(PChar(SysErrorMessage(last)));
ShowMessage(SysErrorMessage(last));
// end;
end;
end;
function TForm1.InitReadDirCh: boolean;
var
I : Integer;
OVPD : OVERLAPPED;
p: Pointer;
begin
result := true;
OVPD.Internal := 0;
OVPD.InternalHigh := 0;
OVPD.Offset := 0;
OVPD.OffsetHigh := 0;
OVPD.hEvent := FhDirChangeEvent;
if not ReadDirectoryChangesW(FhSpyDir, @FSpyBufArray,
SizeOf(FSpyBufArray),
false,
FILE_NOTIFY_CHANGE_LAST_WRITE,
nil,
@OVPD,
nil) then
Result := false;
end;
end.
Анонимщик1 (2007-03-12 18:13:00) [1]Пардоньте, я же сказал: "при случае".
tesseract (2007-03-12 17:58:00) [2]
> И ?)
Баланс уже отрицательный.
Сергей М. (2007-03-12 14:47:00) [3]
> Анонимщик1 (12.03.07 13:10) [33]
И ?)
Анонимщик1 (2007-03-12 13:10:00) [4]Спасибо, я записал
Сергей М. (2007-03-12 13:05:00) [5]
> Анонимщик1 (12.03.07 12:47) [30]
> почему не возникало исключения
Это уж как повезет)
Сергей М. (2007-03-12 13:02:00) [6]
> Анонимщик1 (12.03.07 12:41) [28]
R276617073300
Z776774471136
Анонимщик1 (2007-03-12 12:47:00) [7]В любом случае была ошибка, а почему не возникало исключения - другой вопрос.
Сергей М. (2007-03-12 12:42:00) [8]
> не зная этого, нельзя было лучше описать проблему
Но проблема эта никак не связана ни с наличием ни с отсутствием упомянутого тобой блока try..finally/except. Что он есть, что его нет - исключение по упомянутой причине будет возбуждено в любомслучае.
Анонимщик1 (2007-03-12 12:41:00) [9]Сергей, Вы бы написали номер вашего кошелька, я бы Вам счет при случае пополнил бы.
Анонимщик1 (2007-03-12 12:36:00) [10]Большое спасибо.
Да, облажался я, признаю. Хотя то, что время жизни должно быть не меньше времени ожидания, должно было быть очевидным.
Но согласитесь, что, не зная этого, нельзя было лучше описать проблему.
Сергей М. (2007-03-12 12:11:00) [11]Еще точнее - время жизни overlapped-структуры в асинхронной операции должно быть не меньше времени ожидания асинхронного события.
Сергей М. (2007-03-12 12:05:00) [12]Переменная OVPD : OVERLAPPED д.б. статическкой !
Анонимщик1 (2007-03-12 11:23:00) [13]Сергей, у меня такого пункта меню нет, сколько бы Вы не сомневались. Заранее согласен, что я олух.
Я готов даже пойти на то, чтобы признать, что мои объяснения путаные, хотя они самые что ни есть конкретные, т.е. точные и детально описывающие картину происходящего.
Несмотря на Ваш довольно нетерпеливый и грубый тон, все-таки прошу загрузить код в редактор и проверить, насколько я неправ.
Сергей М. (2007-03-12 11:16:00) [14]
> Вы имели в виду отладчик, а не главное меню?
Я имер ввиду главное меню окна самого IDE.
В нем есть пункт Search, в котором д.б. подпункт Find Error ...
> почему Вы решили, что я не делаю пошаговой трассировки?
Потому что именно пошаговая трассировка и покажет конкретнуюпроблемную строку. Из твоих путаных объяснений она до сих пор не известна.
Анонимщик1 (2007-03-12 11:00:00) [15]> Глубоко сомневаюсь, что его нет в D2006.
Вы имели в виду отладчик, а не главное меню?
> Как определил ? Без пошаговой трассировки-то ?
Я никак не могу понять, почему Вы решили, что я не делаю пошаговой трассировки? Из чего Вы вывели такое заключение?
Сергей М. (2007-03-12 10:56:00) [16]
> такого пункта меню у меня нет (Delphi 2006)
В D7 есть.
Глубоко сомневаюсь, что его нет в D2006.
> AV происходит уже после выхода из функции
Как определил ? Без пошаговой трассировки-то ?
Анонимщик1 (2007-03-12 10:50:00) [17]Адрес нулевой, такого пункта меню у меня нет (Delphi 2006), но AV происходит уже после выхода из функции.
Сергей М. (2007-03-12 10:37:00) [18]
> непонятна причина, из-за которой она возникает
Бессмысленно искать причину, не зная источника проблемы ( конкретнойстроки кода, вызвавшей исключение)
Анонимщик1 (2007-03-12 10:36:00) [19]Да, при замене finally на except поведение не меняется
Сергей М. (2007-03-12 10:36:00) [20]
> Анонимщик1 (12.03.07 10:31) [15]
Вот ты получил сообщение об исключении "... Access Violation at XXXXXXXX....".
В меню Search - > Find Error .. вводишь этот самый адрес XXXXXXXX и отладчик покажет тебе строку текста твоей программы, выполнение которой привело к искл-ю.