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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.033 c
3-1103010445
Zilog
2004-12-14 10:47
2005.01.16
БД + потоки


3-1103092981
Layner
2004-12-15 09:43
2005.01.16
Подскажите, как вставить в колонку NULL значение в событии


14-1104077438
maxz
2004-12-26 19:10
2005.01.16
цитаты про вино


1-1104149785
markers
2004-12-27 15:16
2005.01.16
На тему ini файлов


1-1104757124
Andrewp
2005-01-03 15:58
2005.01.16
Распознование функций





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский