Форум: "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)^.QueryInterfaceThunk;
case QueryInterfaceThunk.AddInstruction of
AddByte: Inc(PChar(Result), QueryInterfaceThunk.AdjustmentByte);
AddLong: Inc(PChar(Result), QueryInterfaceThunk.AdjustmentLong);
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