Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

_Release и VCL [Delphi, Windows]


SeLarin ©   (2004-10-25 08:33:00) 

Привет, Мастера! Начал изучать 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?


SeLarin   (2004-10-25 14:06:00) [1]

Спасибо. Просто и ясно!


VMcL   (2004-10-25 10:38:00) [2]

P.S.
Для того, чтобы явно освободить экземпляр интерфейса (это не так уж часто нужно) следует просто присвоить переменной интерфейсного типа константу nil:
SomeIntf := nil; // Здесь компилятор автоматически вставит вызов Release при необходимости.


VMcL   (2004-10-25 10:35:00) [3]

>> SeLarin ©  (25.10.04 08:33)

В Object Pascal экземпляры интерфейсов являются объектами с управляемым временем жизни. Вызов Release компилятор вставляет автоматически в том месте, где переменная интерфейсного типа выходит из области видимости.


Наверх

Титульная страница Поиск, карта сайта Написать письмо