Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.12.30;
Скачать: CL | DM;

Вниз

Как запретить авто удаление наследнику TInterfacedObject?   Найти похожие ветки 

 
Kolan ©   (2007-12-04 14:31) [0]

Здравствуйте,
 Был у меня синглетон наследник TObject. Понадобилось чтобы он поддерживал интерфейс, сделал наследником TInterfacedObject. Теперь при при передаче его как интерфейса в процедуру, он, по всей видимости удаляется по её завершении.

Вопрос как корректно предотвратить авто удаление?


 
Skyle ©   (2007-12-04 14:36) [1]

Для начала корректно с ним работать как с интерфейсом.

Можно ещё плюнуть на TInterfacedObject и самостоятельно реализовать методы IUnknown.


 
Kolan ©   (2007-12-04 14:38) [2]

> Для начала корректно с ним работать как с интерфейсом.


Для начала корректно с ним работать как с интерфейсом.

Как интерфейс он мне нужен в одном месте, которое я добавил только что. Во всех остальных надо оставить старое поведение синглетона.


 
MetalFan ©   (2007-12-04 14:46) [3]


> Как интерфейс он мне нужен в одном месте, которое я добавил
> только что.


> плюнуть на TInterfacedObject и самостоятельно реализовать
> методы IUnknown.

;)


 
Kolan ©   (2007-12-04 14:48) [4]

Вот у меня есть коммен Egи по поводу сабжа.

[3] Ega23 ©   (09.11.07 10:34)

> И скопипастиьть их из TInterfacedObject, так?

Это уж как тебе надо. Лично я внутри _AddRef и _Release счётчик сылок в —1 держу, если не хочу, чтобы объект автоматом разрушилсо.
+

[3] MetalFan ©   (04.12.07 14:46)
> ;)


А как это(сылок в —1 держу) сдеать правильно?


 
Kolan ©   (2007-12-04 14:53) [5]

Я понимаю вроде что RefCount := —1 но опасаюсь что это не все что надо&#133


 
Kolan ©   (2007-12-04 15:15) [6]

Проблемма в том, что полсе того как я добавил поддержку интерфейса стало вылетать ав при удалении синглетона:
initialization
finalization
StartUpController.Free;


Более нигде он не разрушается.


 
Skyle ©   (2007-12-04 15:19) [7]


> Kolan ©   (04.12.07 15:15) [6]
> Более нигде он не разрушается.

Тобой.


 
Reindeer Moss Eater ©   (2007-12-04 15:21) [8]

_addref в качестве подпорки. Если неохота разбираться в отличиях объектных и  интерфейсных ссылок.


 
Kolan ©   (2007-12-04 15:22) [9]

> Тобой.

Мной лично нет. Следовательно все из-за того, что я его передаю в процедуру:

function TUserLoginForm.ShowLoginDialog(ALogin: string;
 ALoginVisitor: ILoginVisitor): Boolean;
begin
 if Assigned(ALoginVisitor) then
 begin
   FLoginVisitor := ALoginVisitor;
   UserNameEdit.Text := ALogin;
   Result := inherited ShowModal = mrOk;
 end;
end;


Где FLoginVisitor поле класса. А сам этот класс(TUserLoginForm) уничтожается и видимо уничтожает и FLoginVisitor&#133 Как предотвртить?

function TStartUpController._AddRef: Integer;
begin
 FRefCount := —1;
end;

function TStartUpController._Release: Integer;
begin
 FRefCount := —1;
end;  


Меняет ав на инвалид поинтер оперэйшн &#133


 
Игорь Шевченко ©   (2007-12-04 15:22) [10]

Унаследуй не от TInterfacedObject, а от TComponent


 
Kolan ©   (2007-12-04 15:23) [11]


> Если неохота разбираться в отличиях объектных и  интерфейсных
> ссылок.


Как я понимаю са интр ссылками следят и если счетчик становится 0, то объект уничтожается, но как корректно предотвратьть это не пойму.


 
Kolan ©   (2007-12-04 15:26) [12]


> Унаследуй не от TInterfacedObject, а от TComponent


Да так корректно все, благодарю — решение.


function TComponent._AddRef: Integer;
begin

 if FVCLComObject = nil then
   Result := —1   // —1 indicates no reference counting is taking place
 else
   Result := IVCLComObject(FVCLComObject)._AddRef;

end;


А, Result := —1;&#133


 
Kolan ©   (2007-12-04 15:33) [13]

Унаследовался от TInterfacedObject"а

Сделал так:

function TStartUpController._AddRef: Integer;
begin
 Result := —1;  {No ref countiong}
end;

function TStartUpController._Release: Integer;
begin
 Result := —1;  {No ref countiong}
end;


Ошибок не насажал?


 
Reindeer Moss Eater ©   (2007-12-04 15:34) [14]

После создания экземпляра, просто вызови _AddRef и никто его не убъет кроме тебя самого.


 
Skyle ©   (2007-12-04 15:35) [15]

> Kolan ©   (04.12.07 15:33) [13]
Да не видно


 
Джо ©   (2007-12-04 15:36) [16]

> [13] Kolan ©   (04.12.07 15:33)
> Ошибок не насажал?

Так нормально.


 
Kolan ©   (2007-12-04 15:58) [17]

> Так нормально.

Ок
> Да не видно

Сенкс.
> После создания экземпляра, просто вызови _AddRef и никто
> его не убъет кроме тебя самого.


Благодарю вопрос решен :)


 
oxffff ©   (2007-12-04 19:40) [18]


> Джо ©   (04.12.07 15:36) [16]
> > [13] Kolan ©   (04.12.07 15:33)
> > Ошибок не насажал?
>
> Так нормально.


И все же потенциально ошибка может возникнуть.

 TKolanClass=class(TInterfacedObject,Iunknown)
 public
 function _AddRef: Integer;stdcall;
 function _Release: Integer;stdcall;
 destructor destroy;override;
 end;

{ TKolanClass }

destructor TKolanClass.destroy;
begin
Showmessage("Object is under destruction");
inherited;
end;

function TKolanClass._AddRef: Integer;
begin
result:=-1;
end;

function TKolanClass._Release: Integer;
begin
result:=-1;
end;

procedure TForm1.Button1Click(Sender: TObject);
var KolanClass:TKolanClass;
   a:IUnknown;
   c:TinterfacedObject;
begin
KolanClass:=TKolanClass.Create;
a:=KolanClass;
a:=nil;
a:=KolanClass as Iunknown;
a:=nil;

c:=KolanClass;
a:=c;    //_Addref от TInterfacedObject
a:=nil;  // _Release от TInterfacedObject

{
Здесь объект KolanClass уже разрушен.
}
end;


 
DrPass ©   (2007-12-04 21:38) [19]


> Унаследовался от TInterfacedObject"а
>
> Сделал так:
>
> function TStartUpController._AddRef: Integer;
> begin
>  Result := —1;  {No ref countiong}
> end;
>
> function TStartUpController._Release: Integer;
> begin
>  Result := —1;  {No ref countiong}
> end;
>
> Ошибок не насажал?

Немного насажал. Зачем наследоваться от TInterfacedObject? Чтобы при случае добраться до старой версии _Release, и таки грохнуть объект?


 
Джо ©   (2007-12-04 21:54) [20]

А, точно, я сразу и не заметил, что от TInterfacedObject наследуемся.


 
Ins ©   (2007-12-04 23:35) [21]

А я в таких случаях обычно наследуюсь от TInterfacedPersistent, т.к. TComponent на мой взгляд несколько избыточен. Или можно, как уже сказали, написать свой класс = class(TObject, IInterface) и самому реализовать методы _AddRef и _Release, просто возвращая в них -1.


 
Kolan ©   (2007-12-05 08:38) [22]

> Зачем наследоваться от TInterfacedObject? Чтобы при случае
> добраться до старой версии _Release, и таки грохнуть объект?

Нет, ошибка это.

Так в итоге как сделать лучьше?
Отнаследоватьсяот TInterfacedPersistent.

Или
TObject, IInterface
А QueryInterface в этом случае просто скопировать? Откуда?


 
oxffff ©   (2007-12-05 08:48) [23]


> Kolan ©   (05.12.07 08:38) [22]


Решений может быть несколько.
Что у тебя за задача?


 
Kolan ©   (2007-12-05 09:04) [24]

> Что у тебя за задача?

Был синглетон. У него была операция functon Foo: Integer;

Есть совершенно независимый модуль, в котором есть класс и в нем операция procedure DoSmth(Visitor: IVisitor);


Где
IVisitor = interface
 functon Foo: Integer;
end;


В синглетоне у же есть Foo и она делает что что надо, осталось только сделать, чтобы синглетон поддкрживал IVisitor.
Вот сделать чтобы поддерживал(чобы передать его(синглетон) в DoSmth) — и есть задача, в остальном он должен работать так, как и работал.


 
oxffff ©   (2007-12-05 09:50) [25]

AClass=class(Tobject)
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
end;

BClass=class(AClass,IVisitor)
function Foo: Integer;
end;

Если необходима работа оператора AS, тогда
AClass=class(Tobject,Iinterface)


 
Kolan ©   (2007-12-05 09:55) [26]

Зачем мне нужен AClass?

Сейчас отнаследовлся от TInterfacedPersistent, собстренную реализацию _AddRef и _Release закоментил, работает. Так нормаль сделать?


 
oxffff ©   (2007-12-05 10:04) [27]


> Kolan ©   (05.12.07 09:55) [26]


Если наследуешься от TInterfacedPersistent, то тогда в твоем случае ничего делать не нужно.


 
oxffff ©   (2007-12-05 10:07) [28]


> oxffff ©   (05.12.07 10:04) [27]


Главное не перекрывать  function TPersistent.GetOwner: TPersistent;dynamic;


 
Игорь Шевченко ©   (2007-12-05 10:08) [29]

Все хорошо, но я все-таки до конца не понимаю смысл тщательного измерения дли шага у мерина, которого ведут на живодерню.


 
Kolan ©   (2007-12-05 10:28) [30]

> Все хорошо, но я все-таки до конца не понимаю смысл тщательного
> измерения дли шага у мерина, которого ведут на живодерню.

Мы вашу феню не коцаем :)


 
Ins ©   (2007-12-05 10:41) [31]


> А QueryInterface в этом случае просто скопировать? Откуда?

Скопировать, причем все равно, у TInterfacedPersistent или TInterfacedObject, они одинаковы. Их вызов просто сводится к вызову GetInterface:
function TInterfacedObject.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
 if GetInterface(IID, Obj) then
   Result := 0
 else
   Result := E_NOINTERFACE;
end;

function TInterfacedPersistent.QueryInterface(const IID: TGUID;
 out Obj): HResult;
const
 E_NOINTERFACE = HResult($80004002);
begin
 if GetInterface(IID, Obj) then Result := 0 else Result := E_NOINTERFACE;
end;


 
Kolan ©   (2007-12-05 10:50) [32]

Удалено модератором
Примечание: Жаргон смени


 
Kolan ©   (2007-12-05 16:43) [33]

Продолжение вопроса.

Похожий момент, но только теперь у синглетона уже есть предок.
TSystemController = class(TIndexedDomainListObjectListner, IPatientSearchVisitor)

Следовательно я сам добавил
function _AddRef: Integer; stdcall;
   function _Release: Integer; stdcall;
   function QueryInterface(const IID: TGUID; out Obj): HResult;


Вот ругается:
[Error] &#133 Declaration of "QueryInterface" differs from declaration in interface "IPatientSearchVisitor"

Где

IPatientSearchVisitor = interface
   ["{E977F349-6656-4416-B407-BAB207CBE051}"]
   function GetPatients(PatientsRequest: IPatientsRequest): TDataSet;
 end;


Как это понять?


 
Kolan ©   (2007-12-05 16:55) [34]

stdcall; забыл написать&#133 Вопрос снят


 
Ins ©   (2007-12-05 16:56) [35]

stdcall не везде



Страницы: 1 вся ветка

Текущий архив: 2007.12.30;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.022 c
15-1195982608
Иван Д.
2007-11-25 12:23
2007.12.30
Гиперкуб


2-1196846087
slavon
2007-12-05 12:14
2007.12.30
Компонент типа "проводника"


2-1196752097
allucard
2007-12-04 10:08
2007.12.30
Работа с записями


2-1197013873
Rimd
2007-12-07 10:51
2007.12.30
OnMouseUp


2-1196421856
Yury_FK
2007-11-30 14:24
2007.12.30
aProcessEntry32 Глюченный???