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

Вниз

Как получить объект по интерфейсу?   Найти похожие ветки 

 
Mx   (2005-04-22 17:16) [0]

Привет, Мастера! Согласно "ребрендингу" поменял свой ник, который и мне порядочно надоел, но это к делу не относится...

Вопрос может совсем дикий, но он в названии (ламером прошу не обзывать). Имеем переменную типа IUnknown, можно ли получить ссылку на сам объект? Или эта ссылка и есть то, что мне надо?


 
VMcL ©   (2005-04-22 17:21) [1]

>>Mx   (22.04.05 17:16)

QueryInterface
?


 
Mx   (2005-04-22 17:23) [2]

Так эээ вроде QueryInterface возвращает указатель на интерфейс, а мне надо наоборот, типа "QueryObject"...


 
DiamondShark ©   (2005-04-22 17:30) [3]

В общем виде -- никак.
За интерфейсом может не скрываться вообще никакого "объекта".

Что значит "сам объект"?


 
Mx   (2005-04-22 17:36) [4]

"Сам объект" - это то бишь тот, кто реализует. В-общем есть два объекта, но один о другом знает только по интерфейсу (а точнее у него список интерфейсов в IInterfaceList), но мне нужно получить в одном местечке указатель на объект, чтобы проверить значение его свойства. Конечно, можно свойство в интерфейсе описать, но так абстракция теряется, чего не хотелось бы... Хранить список объектов мне неудобно.

Так походу нельзя, угу?

type
...
 TImplementer = class(TObject, IInterface)
...

var
 I: IInterface;
begin
 ...
 if TImplementer(I).SomeProp then...
 ...
end;


 
DiamondShark ©   (2005-04-22 17:45) [5]

Реализующий интерфейс объект ты сам пишешь, или он уже есть сторонний?


 
Mx   (2005-04-22 18:01) [6]

Нет, оба пишу сам. Один - хранит списки экземпляров другого, а вернее список одного из интерфейсов этих экземпляров. Во многом это ради удобства и абстракции, но в принципе можно хранить и сами объекты...

P.S. Я прикинул, наверное, такое свойство и интерфейсу нужно, потому как будет еще сторонняя прога, которая с этим делом будет работать и там иногда эта инфа тоже понадобится, так что вынесу свойство в интерфейс.


 
Mx   (2005-04-22 18:04) [7]

А все-таки? И как из переменной A получить указатель на B или они все-таки не отличаются?

var
 A: IInterface;
 B: TInterfacedObject;
begin
 B := TInterfacedObject.Create;
 ...
 A := B as IInterface;
 ...
end;


 
Набережных С. ©   (2005-04-22 18:08) [8]


> Mx   (22.04.05 17:36) [4]

Даже если объект твой, все равно не надо так делать, ибо противоречит самой концепции интерфейса, а такие нарушения рано или поздно выходят боком. Тем более, что предоставив через интерфейс доступ к объекту ты тем самым как раз и уничтожишь его абстрагированность. Напротив, добавив в интерфейс метод проверки интересующего свойства ты ничего не теряешь. Просто те объекты, которые такого свойства не имеют, будут возвращать результатом этого метода E_NOTIMPL. Вполне обычная практика.

> Mx   (22.04.05 18:04) [7]

Да, так нормально. И они отличаются:)


 
DiamondShark ©   (2005-04-22 18:10) [9]


> Нет, оба пишу сам.

Тогда можно использовать приватный интерфейс как backdoor:

IBackdoor = interface
["{B094B0E6-ADE3-4818-8165-3F9F99123EC8}"]
function GetObject: TObject;
end;

TMyImpl = class(TObject, IInterface, IBacdoor)
...
end;


 
Skier ©   (2005-04-22 18:10) [10]

Примерно так :

IYourInterface = interface(...)
["{C9FC9806-2C28-4C3E-B265-C441398AC574}"]
function GetInstance : TObject;
property Instance : TObject read GetInstance; //"слабая" ссылка
end;


 
MBo ©   (2005-04-22 18:13) [11]

оно?


function GetImplementingObject(const I: IInterface): TObject;
const
 AddByte = $04244483; // opcode for ADD DWORD PTR [ESP+4], Shortint
 AddLong = $04244481; // opcode for ADD DWORD PTR [ESP+4], Longint
type
 PAdjustSelfThunk = ^TAdjustSelfThunk;
 TAdjustSelfThunk = packed record
   case AddInstruction: longint of
     AddByte : (AdjustmentByte: shortint);
     AddLong : (AdjustmentLong: longint);
 end;
 PInterfaceMT = ^TInterfaceMT;
 TInterfaceMT = packed record
   QueryInterfaceThunk: PAdjustSelfThunk;
 end;
 TInterfaceRef = ^PInterfaceMT;
var
 QueryInterfaceThunk: PAdjustSelfThunk;
begin
 Result := Pointer(I);
 if Assigned(Result) then
   try
     QueryInterfaceThunk := TInterfaceRef(I)^.QueryInterfa­ceThunk;
     case QueryInterfaceThunk.AddInstruc­tion of
       AddByte: Inc(PChar(Result), QueryInterfaceThunk.Adjustment­Byte);
       AddLong: Inc(PChar(Result), QueryInterfaceThunk.Adjustment­Long);
       else     Result := nil;
     end;
   except
     Result := nil;
   end;
end;

Hallvard Vassbotn


 
Mx   (2005-04-22 18:13) [12]

Спасибо, мужики, все узнал что хотел. Добавлю свойство в интерфейс, а то в натуре какой-то огород получается ненужный.

P.S. А с IBackdoor"ом прикольно! Взял на заметку.


 
Skier ©   (2005-04-22 18:20) [13]

>MBo ©   (22.04.05 18:13) [11]
Классно ! Это откуда ?


 
Набережных С. ©   (2005-04-22 18:40) [14]


> MBo ©   (22.04.05 18:13) [11]

Ай-я-яй! Чистое хакерство, как не стыдно!?
:))))))
Присоединяюсь к Skier ©   (22.04.05 18:20) [13]. Действительно классно!


 
MBo ©   (2005-04-22 20:08) [15]

>Это откуда ?
из borland-овских ньюсгрупп, 2002 год, автор указан.
Интересно, что функция была в виде задачи - Что оно делает?- (идентификаторы приводились несамообъясняющие)


 
vuk ©   (2005-04-22 20:43) [16]

to MBo:
Оно конечно да, достать можно. ТОлько для нормальной работы интерфейс должен быть гарантированно реализован классом Delphi. А иначе можно такого надоставать, что мало не покажется. Уж лучше IBackdoor. Во всяком случае спасает от упадания лицом в салат. Кстати, в VCL как раз такой способ используется - TComponent реализует IInterfaceComponentReference.


 
Mx   (2005-04-23 11:48) [17]


> vuk ©   (22.04.05 20:43) [16]
>
> ТОлько для нормальной работы
> интерфейс должен быть гарантированно реализован классом
> Delphi.
>


Помнится в справке Delphi я встречал, что объект в памяти формируется с соблюдением совместимости с COM. Наверняка, объекты других языков тоже таковы, потому код (хотя я там мало что понял) скорее всего универсальный.


 
DiamondShark ©   (2005-04-23 12:59) [18]


> Наверняка, объекты других языков тоже таковы, потому код
> (хотя я там мало что понял) скорее всего универсальный.

За интерфейсом может не стоять вообще никакого "объекта" в классическом понимании.


 
Mx ©   (2005-04-23 13:08) [19]


> DiamondShark ©   (23.04.05 12:59) [18]
>
> За интерфейсом может не стоять вообще никакого "объекта"
> в классическом понимании.

Я имел ввиду случай, когда есть переменная, ссылающаяся на какой-либо интерфейс какого-либо объекта


 
MBo ©   (2005-04-23 14:49) [20]

>vuk ©   (22.04.05 20:43) [16]
Конечно, при использовании любых хакерских недокументированных штучек автор должен себе отдавать отчет о риске и о границах применимости.

Про IBackDoor - что имелось в виду - техника, использованная в TComponent.IntfGetComponent - со введением специального интерфейса именно для обеспечения возможности Subj-евой цели?


 
Набережных С. ©   (2005-04-23 16:10) [21]


> Mx ©   (23.04.05 13:08) [19]

Что-то ты где-то не там читал. Или не так понял. Даже когда есть ссылка "на какой-либо интерфейс какого либо объекта". Ибо спецификация COM не устанавливает ни малейших ограничений на РЕАЛИЗАЦИЮ интерфейса. И уж тем более не устанавливает НИКАКИХ правил формирования структуры объекта.


 
Mx ©   (2005-04-23 16:29) [22]

Кажется я понял что имеется ввиду (про отсутствие объекта).


 
Набережных С. ©   (2005-04-23 16:48) [23]


> MBo ©   (23.04.05 14:49)
> техника, использованная в TComponent.IntfGetComponent

Имхо, эта "техника" столь же очевидная, сколь и неправильная. И IntfGetComponent ввели, я убежден, как заплатку, предназначив для чисто внутреннего использования.

А код в [11] действительно красивый. Сам по себе, безотносительно к каким-либо теориям:)


 
vuk ©   (2005-04-25 19:12) [24]

to Mx ©   (23.04.05 16:29) [22]:
>Кажется я понял что имеется ввиду (про отсутствие объекта).
Я не знаю, что Вы там поняли, но намекну, что COM-объекты могут быть реализованы на языке, не поддерживающем ООП в принципе.

to Набережных С. ©   (23.04.05 16:48) [23]:
>IntfGetComponent ввели, я убежден, как заплатку, предназначив
>для чисто внутреннего использования.
IntfGetComponent введен именно для получения ссылки на компонент, реализующий интерфейс. Используется при сохранении в потоки published свойств интерфейсного типа. Я бы не сказал, что это заплатка, это скорее можно отнести к внутренним механизмам VCL.


 
Набережных С. ©   (2005-04-25 19:58) [25]


> vuk ©   (25.04.05 19:12) [24]

Насчет сохранения интерфейсных свойств - возможно. Я не в курсе этого момента, упустил, надо будет глянуть, спасибо. Однако я его встречал где-то в местах, не связанных с этим механизмом. Но если так - тем более заплата, для расширения функциональности без кардинальной переделки существующих механизмов. Не было такой возможности изначально заложено - вот и пришлось изворачиваться:)

> это скорее можно отнести к внутренним механизмам VCL.

Это я имел в виду : предназначив для чисто внутреннего спользования
В любом случае, такой подход считаю крайне нежелательным. Хотя я и сам, случалось, упомянал такой способ на этом форуме, но всегда при этом предупреждал, что лучше так не делать. Вот и сейчас не промолчал:))



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

Форум: "Corba";
Текущий архив: 2006.03.05;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.014 c
10-1114175801
Mx
2005-04-22 17:16
2006.03.05
Как получить объект по интерфейсу?


1-1138640470
Igor23
2006-01-30 20:01
2006.03.05
Работа с COM объектами!!! Закладка DataSnap.....


2-1140241181
Хинт
2006-02-18 08:39
2006.03.05
Помогите разобраться с TSocket (WinSock)


15-1139412550
oldman
2006-02-08 18:29
2006.03.05
Вопросик не продельфи, но ...


15-1139479036
Kolan
2006-02-09 12:57
2006.03.05
Генератор пустого календаря.





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