COM-объект

PoweRDeaD
Дата: 08.06.2009 16:03:15
Создается COM-объект
var
  RecoverDB : OleVariant;
begin
  try
     RecoverDB := CreateOleObject('dbk_Extract.DBUtils');
     ......
  finally
    RecoverDB := Unassigned;
  end;

Но DLL c этим COM-объектом, после Unassigned все равно остается в памяти. Можно это как-то победить?
_Vasilisk_
Дата: 08.06.2009 23:35:33
Dll выгружается, когда функция DllCanUnloadNow() вернет значение S_OK. Обычно она возвращает это значение, когда счетчик ссылок интерферсных объектов достигент 0 и они уничтожатся.

А вот когда система вызовет это функцию, в общем случае неизвестно. Вызвав функцию СoFreeUnusedLibrary() Вы можете сказать системе пересмотреть свои взгляды и вызвать функцию DllCanUnloadNow() немедленно.

P.S. В 99% случаев не нужно предпринимать никаких специальных шагов по выгрузке dll. Система умная - сама разберется.

С уважением, Vasilisk
Petro123
Дата: 08.06.2009 23:54:12
PoweRDeaD,
некоторые приложения, например excell требуют не только обнулить переменную, но и закрыть рабочую книгу (т.е. смотря как написан OLE)
_Vasilisk_
Дата: 08.06.2009 23:57:32
Конечно. Логика реализации DllCanUnloadNow() у серверов может отличаться

С уважением, Vasilisk
Гаджимурадов Рустам
Дата: 09.06.2009 00:01:16
ОФФ

Гм... Вот я читаю такие посты и все больше и больше
проникаюсь уважением. Побольше бы таких. Спасибо. :)
PoweRDeaD
Дата: 10.06.2009 09:30:40
Нарисовалась такая проблема:
создается COM-объект и в цикле вызывается его метод Execute несколько раз.
В этом методе корректно создаются и уничтожаются собственные классы.
Метод Destroy объекта отрабатыватся при RecoverDB := Unassigned
Но при закрытии вызывающего модуля (exe-шника) возникает Exception:
The instruction at "0x079e8030" referenced memory at "0xefe54c7c". The memory could not be "written".
Было замечено, что если цикл отрабатывает нечетное кол-во раз, то ошибки при закрытии приложения не возникает, при четном кол-ве раз - ошибка возникает всегда.
Трассировка показала, что Exception возникает в юните SysInit:
unit System
  procedure _Halt0;
  ....
     if InitContext.DllInitState = 1 then
      InitContext.ExitProcessTLS;

      if InitContext.DllInitState <> 0 then
      ExitDll;
  ....
 
unit SysInit;
procedure       ExitProcessTLS;
begin
  if @TlsLast = nil then     // здесь ошибка!!!
    Exit;
  ExitThreadTLS;
  if TlsIndex <> -1 then
    TlsFree(TlsIndex);
end;

Уже весь мозг сломал....
Petro123
Дата: 10.06.2009 09:42:08
PoweRDeaD,
com твой? поставь туда в destroy messagebox и следи за вызовами.
Возможно счётчик нарушен и идёт дважды destroy уже после уничтожения
Petro123
Дата: 10.06.2009 09:47:56
PoweRDeaD

В этом методе корректно создаются и уничтожаются собственные классы.

без этого метода com закрывается нормально?
Значит текст выше - неправда.
PoweRDeaD
Дата: 10.06.2009 09:52:15
Petro123,
Destroy - отрабатывает один раз

Без метода Excecute - отрабатывает без ошибок
Petro123
Дата: 10.06.2009 10:04:07
PoweRDeaD
Petro123,
Destroy - отрабатывает один раз
Без метода Excecute - отрабатывает без ошибок

ну дык вырезай из метода куски, пока не найдёшь глючный кусок.