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

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

Помогите найти ошибку в коде [Delphi, Windows]


Cobalt ©   (2004-09-07 09:46:00) 

Увидел этот код в http://www.delphimaster.ru/cgi-bin/forum.pl?id=1094389442&n=3&p=7
Посмотрел его, скомпилировал, запустил по шагам - и не понял - а откуда AV берётся???
Если кто понимает - объясните, пожалуйста.
noname_   (06.09.04 17:06) [120]
program testintf;
{$APPTYPE CONSOLE}

uses
SysUtils;

type
ITest = interface(IUnknown)
  procedure Delete;
end;

TTest = class(TInterfacedObject, ITest)
private

protected
  function _AddRef: Integer; stdcall;
  function _Release: Integer; stdcall;
public
  procedure Delete;
end;

var
gTest: ITest;

procedure TTest.Delete;
begin
Free;
end;

function TTest._AddRef: Integer;
begin
Result := -1;
end;

function TTest._Release: Integer;
begin
Result := -1;
end;

procedure NewObj;
begin
gTest := TTest.Create;
end;

function GetObj: ITest;
begin
Result := gTest;
end;

procedure DoTest;
var
i: Integer;
s1: string;
begin
NewObj;
GetObj.Delete;
for i := 1 to 500 do
  s1 := StringOfChar(#0, 200000);
end;

begin
try
  DoTest;
  WriteLn('all right');
except
  on E: Exception do
    WriteLn(E.Message)
  else
    WriteLn('unknown exception');
end;
end.


VMcL   (2004-09-08 13:54:00) [1]

>> Cobalt ©  (08.09.04 11:51) [2]

> 2) Класс, реализующий интерфейсы, не имеет права уничтожаться в случае если он предоставил хоть один "экземпляр" (?) интерфейса.

Естественно. Именно для этого используется автоматический подсчет ссылок, котрый здесь "внаглую отключен".


Cobalt   (2004-09-08 11:51:00) [2]

Итак, что я смог выяснить - в конце процедуры DoTest вызывается IntfClear
Как я понял, вызывается она для интерфейса, к которому мы (я? кому как удобнее) обращались GetObj.Delete;
Как оказывается, для этого интерфейса резервируется место в стеке (скрытая переменная), и потом он освобождается.

Итого:
1) Интерфейс (реализация методов интерфейса) не должен освобождать реализующий его объект класса.
2) Класс, реализующий интерфейсы, не имеет права уничтожаться в случае если он предоставил хоть один "экземпляр" (?) интерфейса.


Ломброзо   (2004-09-07 11:31:00) [3]

Use Debug DCUs + Call Stack


Наверх

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