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

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

Цикл по элементам TInterfaceList


harisma ©   (2011-06-06 11:40:00) 

Мне необходимо организовать цикл по элементам интерфейсного листа и при нахождении нужных элементов их выбросить из него. С этой целью написал следующую процедурку:

procedure CloseProtocols(const AProtocolID: WideString);
var
 i: Integer;
 LProtocolID: AnsiString;
 IProtocol: IS4VPAProtocols;
begin
 FProtocolList.Lock;
 try
   if (AProtocolID = '') then
   begin
     FProtocolList.Clear;
     Exit;
   end

   for i := FProtocolList.Count - 1 downto 0 do
   try
     if (FProtocolList[i].QueryInterface(IS4VPAProtocols, IProtocol) = S_OK) then
     begin
       if (AProtocolID <> '') then
         LProtocolID := FloatToString(IProtocol.ProtocolID);
       if (AProtocolID = '') or (AProtocolID = LProtocolID) then
       begin
         IProtocol.CloseMean;
         IProtocol.Server := nil;
         if (AProtocolID <> '') then
           FProtocolList.Remove(IProtocol);
       end;
     end;
   except
   end;
 finally
   FProtocolList.Unlock;
 end;
end;

Но вот проблема: После того, как первый, удовлетворяющий условие элемент найден и удален из списка, попытка взять QueryInterface у следующего элемента списка приводит к AccessViolation.
Никак не пойму, в чем же проблема? Цикл вроде правильный. В списке присутствует 2 интерфейса. Прошу помощи...


harisma   (2011-06-07 10:35:00) [1]


> до нуля не дойдет

А вот и не правда. Хотя, я ведь не привел полный текст процедуры. В моем случае именно и происходило разрушение интерфейса, не смотря на то что ссылка на него была в листе.


_Юрий   (2011-06-06 20:27:00) [2]


> Ошибка решилась.


Ошибка скрылась. Данный код

>  LProtocol := nil; - это я дописал

и так будет вызван компилятором сразу после выхода из локальной процедуры.
И никакое это не "разрушение интерфейса". Это уменьшение счетчика ссылок, который в данном случае до нуля не дойдет потому, что есть еще ссылка в листе.

Похоже, ты где-то память попортил.


harisma   (2011-06-06 15:55:00) [3]

Ошибка решилась. Проблема была в том, что когда я ЗАПОЛНЯЛ этот список интерфейсами, сами интерфейсы не разрушал в той процедуре, где заполнял. Другими словами было:

procedure ...
var
 LProtocol: IProtocol;
...
begin
...
 Lprotocol := CreateComObject(...)
 LProtocol.Init.
 FProtocolList.Add(Lprotocol);
end;

стало

procedure ...
var
 LProtocol: IProtocol;
...
begin
...
 Lprotocol := CreateComObject(...)
 LProtocol.Init.
 FProtocolList.Add(Lprotocol);
  LProtocol := nil;- это я дописал
end;


anonims   (2011-06-06 14:47:00) [4]


>          IProtocol.Server := nil;

отключаем интерфейсный объект от сервера?
сам интерфейс остается.
Если другой интерфейс из списка тоже на этом объекте. то AV вероятно.
Iprotokol:=nil; наверное так?


makvell   (2011-06-06 13:38:00) [5]

А... там даунту. Сорри, проглядел :(


makvell   (2011-06-06 13:37:00) [6]

Предположение: Мы идем по i, длинна списка = 2, нашли первый, удалили. Второй стал первым, а мы пытаемся взять по i следующий, которого какбы и нет.


KSergey   (2011-06-06 12:29:00) [7]

FProtocolList.Remove(IProtocol);

Есть уверенность, что из списка здесь удаляется именно текущий i-й элемент? или я неправильно понимаю принцип работы TInterfaceList?


harisma   (2011-06-06 12:17:00) [8]

Так не помогает. Так и было у меня первоначально.


Ega23   (2011-06-06 12:07:00) [9]


>  FProtocolList.Remove(IProtocol);

FProtocolList.Delete(i)


Наверх

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