Текущий архив: 2005.08.07;
Скачать: CL | DM;
Вниз
_Release и VCL Найти похожие ветки
← →
SeLarin © (2004-10-25 08:33) [0]Привет, Мастера! Начал изучать COM и возникла проблема.
Есть код:
procedure TForm1.Button1Click(Sender: TObject);
var
iShLnk: IShellLink;
iPersFile: IPersistFile;
Path: array[0..MAX_PATH] of Char;
pfd: TWin32FindData;
hr: HRESULT;
begin
CoInitialize(nil);
iShLnk:=nil;
iPersFile:=nil;
hr:=CoCreateInstance(CLSID_ShellLink,nil,CLSCTX_INPROC_SERVER,IID_IShellLinkA,iShLnk);
if SUCCEEDED(hr) then
begin
hr:=iShLnk.QueryInterface(IID_IPersistFile,iPersFile);
if SUCCEEDED(hr) then
begin
iPersFile.Load("Path_To_Some_Lnk_File", STGM_READ); // загружаем данные из ярлыка
iPersFile._Release;
end;
if iShLnk.GetPath(Path,MAX_PATH,pfd,SLGP_UNCPRIORITY)=NOERROR then // считывает путь
Application.MessageBox(Path,"Hi!!!",0); // показывает путь из ярлыка
iShLnk._Release;
end;
CoUninitialize;
end;
Формально код написан без ошибок (руки в этом плане вроде бы растут из того места, откуда надо). При запуске на исполнение все работает и сообщение с путем из ярлыка показывается (путь правильный), но при этом при завершении процедуры возникает "External exception C000001D". В модуле Windows значению C000001D соответствует только одна константа - STATUS_ILLEGAL_OPERATION, смысл которой мне установить не удалось. Опытным путем установил, что исключение связано с вызовами метода _Release. Если убрать оба вызова, то исключения не возникает, если любой один - возникает только "Access violation...", но ведь _Release убрать вообще нельзя! Причем исключения странные: отловить и обработать их с помощью try..except не удается.
В связи с этим возникают вопросы: 1) почему возникает исключение? 2) как его избежать?
Кроме того, если данный код использовать (без изменений) в консольной программе, то никаких исключений не происходит. Значит, возникновение исключений каким-то образом связано с VCL?
← →
VMcL © (2004-10-25 10:35) [1]>>SeLarin © (25.10.04 08:33)
В Object Pascal экземпляры интерфейсов являются объектами с управляемым временем жизни. Вызов Release компилятор вставляет автоматически в том месте, где переменная интерфейсного типа выходит из области видимости.
← →
VMcL © (2004-10-25 10:38) [2]P.S.
Для того, чтобы явно освободить экземпляр интерфейса (это не так уж часто нужно) следует просто присвоить переменной интерфейсного типа константу nil:SomeIntf := nil;
// Здесь компилятор автоматически вставит вызов Release при необходимости.
← →
SeLarin © (2004-10-25 14:06) [3]Спасибо. Просто и ясно!
Страницы: 1 вся ветка
Текущий архив: 2005.08.07;
Скачать: CL | DM;
Память: 0.45 MB
Время: 0.024 c