Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.12.30;
Скачать: [xml.tar.bz2];

Вниз

Как запретить авто удаление наследнику 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.007 c
6-1176785568
mail
2007-04-17 08:52
2007.12.30
Получение инфы с удалённого сервера MySql


15-1195825250
@!!ex
2007-11-23 16:40
2007.12.30
Можно узнать кто провайдер у сайта?


15-1196442691
Pazitron_Brain
2007-11-30 20:11
2007.12.30
Не заплатил за инет...


2-1196750879
Kolan
2007-12-04 09:47
2007.12.30
А можно у TreeView отключить рисование пунктирных точек?


2-1196346251
mufan
2007-11-29 17:24
2007.12.30
RichEdit и таблица





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский