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

Вниз

Хрень с интерфейсом   Найти похожие ветки 

 
MgFox   (2004-12-30 10:20) [0]

Есть Интерфейс типа:

IMyIntf = interface
 procedure callMe;
end;

класс к которому сий интерфейс привинчен
TMyClass=class(TObject,IMyIntf) ...
А экземпляр этого класса хранится не в обычной переменной я в переменной типа Pointer валяется на него ссылка.

И соответственно когда я пытаюсь обратиться к методу интерфейса
через указатель на объект
IMyIntf(ptr).callMe;
в ответ получаю Exception типа "Access violation ..."

Сообственно вопрос: как с этой хренью бороться ?


 
Sandman25 ©   (2004-12-30 10:22) [1]

(TMyClass(prt) as IMyIntf).Callme

А вообще лучше хранить в виде IMyIntF, а не pointer


 
Palladin ©   (2004-12-30 10:25) [2]

IMyIntf(ptr^).callMe; только зачем этот разврат...


 
MgFox   (2004-12-30 10:32) [3]

Базовый класс не имеет такого интерфеса и при попыткке сделать
IMyIntf(TBaseClass(ptr)).callMe;
Delphi говорит что такое оно компилять не станет ибо типы IMyIntf и TBaseClass  не совместимы.

PS: Сорри в исходном сообщении обшибочка
класс на самом деле делается так:
TMyClass=class(TBaseClass,IMyIntf) ...


 
MgFox   (2004-12-30 10:33) [4]

to Palladin IMyIntf(ptr^).callMe; не спасает, результат тот-же - Exception


 
Palladin ©   (2004-12-30 10:36) [5]


> Базовый класс не имеет такого интерфеса и при попыткке сделать
> IMyIntf(TBaseClass(ptr)).callMe;

А это вообще порнуха. Почему бы тебе не определить в таком случае этот интерфейс для базового класса? Если все же получение интерфеса проводится точно для именно правильного наследника то есть оператор AS и вообще приведение типов. Это первое. Второе


> А экземпляр этого класса хранится не в обычной переменной
> я в переменной типа Pointer валяется на него ссылка.

Идентификатор экземпляра класса сам по себе уже ссылка. Для чего тебе ссылка на ссылку? И если уж используешь это то и работай тогда с ней как с ptr^


 
Sandman25 ©   (2004-12-30 10:36) [6]

Повторяю.
(TMyClass(prt) as IMyIntf).Callme


 
Digitman ©   (2004-12-30 10:38) [7]


> экземпляр этого класса хранится не в обычной переменной
> я в переменной типа Pointer валяется на него ссылка.


зачем хранить в переменной указатель на объект ? смысл какой ? ты же все равно будешь обращаться к этому объекту через его интерфейс ..
храни там, в переменной, прямо интерфейсную ссылку !
если заранее не знаешь, какой интерфейс там будет храниться, объяви как IUnknown, а в нужный момент приводи к нужному интерф.типу ... примерно так :

var
 ptr: IUnknown;
..

 ptr := TMyClass.Create;

..
 IMyIntf(ptr).Callme


 
MgFox   (2004-12-30 10:41) [8]

to Sandman25
> Повторяю.
> (TMyClass(prt) as IMyIntf).Callme
так нельзя сделать т.к.
наследников базового класса у меня дцать и конкретный тип объекта, с которым осуществляется взаимодействие, неизвестен.
Для этого и был нарисован интерфейс дабы не париться с типом объекта.


 
MgFox   (2004-12-30 10:43) [9]

to Digitman
я не могу его хранить как-то иначе чем через Pointer т.к. хранится оно не у меня, а в компоненте, в которой для хранения объектов есть аттрибут Data:Pointer;


 
MgFox   (2004-12-30 10:48) [10]

to Palladin
//Идентификатор экземпляра класса сам по себе уже ссылка. Для чего тебе ссылка на ссылку? И если уж используешь это то и работай тогда с ней как с ptr^

Если я присваиваю указателю значение так:
ptr := TMyClass.Create();
как мне с ним работать ?


 
Sandman25 ©   (2004-12-30 10:50) [11]

[8] MgFox   (30.12.04 10:41)

Значит нужно завести промежуточный класс с интерфейсом, или добавить поддержку интерфейса прямо в baseclass.


 
Sandman25 ©   (2004-12-30 10:51) [12]

А вообще если есть общий предок, то интерфейсы не нужны. Достаточно описать виртуальный метод в предке.


 
Digitman ©   (2004-12-30 11:32) [13]


> я не могу


что это вдруг не можешь ? еще как можешь !
свойство типа Pointer ничем не отличается от переменной типа пойнтер , все практически так же будет выглядеть и в случае со св-вом ..

но я бы посоветовал наследовать свой TMyClass не от TObject, а от  TInterfacedObject - там уже реализован подсчет ссылок и автоуничтожение объекта при сч-ке ссылок = 0

SomeObject.Data := Pointer(TMyClass.Create as IMyIntf); //происходит инкремент сч-ка ссылок
..
//вызываем интерфейсный метод
IMyIntf(SomeObject.Data).Callme; //инкремента сч-ка ссылок не происходит !
..
//интерфейс более не нужен - декрементируем сч-к ссылок
IMyIntf(SomeObject.Data)._Release;


 
Erik1 ©   (2004-12-30 11:50) [14]

Непонятно что тебе точно нужно, но для общего развития: можно запросить интерфейс у объекта.
var
 IPreview: IPreviewLayer;
begin
 if Assigned(SomeObject.Data) and TObject(SomeObject.Data).GetInterface(IPreviewLayer,
   IPreview) then
IPreview.Callme;


 
Cobalt ©   (2004-12-30 12:59) [15]

Digitman ©   (30.12.04 11:32) [13]
//интерфейс более не нужен - декрементируем сч-к ссылок
IMyIntf(SomeObject.Data)._Release;


Немного здоровой критики:
IMyIntf(SomeObject.Data):=nil; ?


 
kull   (2004-12-30 15:32) [16]

Digitman все правильно написал, помоему этого достаточно.
Типа так и надо:

P: Pointer;

...
IUnknown(P) := MyInterface;
...
IUnknown(P) := nil;
...

Только на всякий случай надо в начале P := nil сделать, если не было раньше инициализации P, а то на присваивании
IUnknown(P) := MyInterface;
Может Exception случиться. Я уже сталкивался с этим.))



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

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

Наверх




Память: 0.51 MB
Время: 0.054 c
14-1104388237
Чеширский_Кот
2004-12-30 09:30
2005.01.16
Верите ли вы...


1-1104358483
ariec
2004-12-30 01:14
2005.01.16
рег компонента


1-1104316034
infom
2004-12-29 13:27
2005.01.16
Никак не получается чтобы RichEdit


1-1104146426
zrv
2004-12-27 14:20
2005.01.16
Как сделать счетчик времени


9-1096094110
Goblin V
2004-09-25 10:35
2005.01.16
Смена видеорежима при переходе на другое приложение без закрытия