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

Вниз

Объясните, пожалуйста, смысл фразы.   Найти похожие ветки 

 
Ins ©   (2008-02-05 13:23) [0]

Здравствуйте. У меня вопрос следующий... Объясните пожалуйста смысл фразы "для совместимости с COM, в Delphi тип классовая ссылка представляет собой указатель на VMT".


 
clickmaker ©   (2008-02-05 13:33) [1]

COM - это интерфейсы.
Интерфейс - это VMT, таблица методов

а где эта фраза живет?


 
Ins ©   (2008-02-05 13:39) [2]


> а где эта фраза живет?


Прошу прощения. Фразу по памяти воспроизвел неверно. Правильно так:
Итак, этот метод возвращает адрес, на который указывают самые первые четыре байта в теле объекта. Нам это вряд ли помогло бы, если бы не знание о совместимости Delphi с COM. Как известно, структура COM-объектов строго стандартизована. В начале объекта должен быть расположен указатель на VMT. Дополнительным подтверждением этому служат константы с именами, начинающимися на vmt*, определенные в модуле System:
Источник - http://rsdn.ru/article/Delphi/delphiabs.xml

Я так понимаю, это справедливо для более старых версий Delphi, так как сейчас по смещениям 0, 4 и 8 в VMT может храниться в общем случае все, что угодно, а не указатели на методы IUnknown


 
хам   (2008-02-05 13:40) [3]

> [2] Ins ©   (05.02.08 13:39)
> так как сейчас по смещениям 0, 4 и 8 в VMT может храниться
> в общем случае все, что угодно

А что изменилось?


 
Ins ©   (2008-02-05 13:44) [4]


> А что изменилось?

В юните System.pas есть такое описание:
vmtQueryInterface    = 0 deprecated;
vmtAddRef            = 4 deprecated;
vmtRelease           = 8 deprecated;

Я так понимаю, раньше первые 4 байта объекта указывали на VMT интерфейса IUnknown, а сейчас вроде бы нет.


 
хам   (2008-02-05 13:48) [5]

> [4] Ins ©   (05.02.08 13:44)
> а сейчас вроде бы нет.

Может и сейчас да, а deprecated, ну потому что просто deprecated, на дворе 21 век, ООП, управляемый код, а здесь по кишкам лазить…


 
Ins ©   (2008-02-05 13:54) [6]


> Может и сейчас да

Эксперимент тоже показывает, что для Delphi 7 там может быть все, что угодно. Т.е. правильно ли я понимаю, что раньше для совместимости с COM в VMT всех классов первые три ячейки были зарезервированы, а получение интерфейса IUnknown сводилось к прочтению первых 4 байт от начала экземпляра, но с тех пор объектная модель несколько изменилась?


 
Ins ©   (2008-02-05 14:01) [7]


> Прошу прощения. Фразу по памяти воспроизвел неверно.


Хотя верно. Там в конце делается такой вывод:
Итак, 4 байта, полученных при вызове TObject.ClassType, указывают в начало таблицы виртуальных методов, декларированных в потомках TObject. Этот вывод можно считать «безопасным» до тех пор, пока Delphi поддерживает совместимость с COM.


 
clickmaker ©   (2008-02-05 14:01) [8]

поменяли способ нахождения ссылки на метод
раньше по vmtQueryInterface и пр.
а теперь по VMTOFFSET IInterface.QueryInterface
см. _IntfCast в system.pas


 
Григорьев Антон ©   (2008-02-05 14:13) [9]


> Ins ©   (05.02.08 13:39) [2]

Фраза "структура COM-объектов строго стандартизована" неправильная. До структуры COM-объекта вообще дела никому нет. Единственное требование к нему - чтобы он умел возвращать указатели на интерфейсы (на бинарном уровне это указатель на указатель на VMT интерфейса). А уж как он сам внутри устроен - не важно. В C++, например, интерфейс - это просто класс, у которого нет полей, а все методы абстрактны и имеют видимость public. Реализация интерфейсов в COM-объекте часто делается множественным наследованием, и этих интерфейсов будет несколько. Соответственно, и несколько VMT будет, и по какому смещению в данных класса они будут располагаться, заранее неизвестно, особенно если наследуются не только интерфейсы, но и классы. И ничего, всё работает.

Вообще, в C++ объявление виртуальных методов в классе означает, что появляется неявное поле void* vPtr, являющееся указателем на VMT. Представьте, что класс наследуется от другого класса, и предок не содержит виртуальных методов, но имеет другие, явно объявленные поля. Тогда vPtr наследника помещается после этих полей, а вовсе не в начало класса, иначе будет нарушена совместимость с предком. Так что в общем случае даже без множественного наследования нельзя предсказать, по какому смещению будет находится указатель на VMT. А в случае множественного наследования в классе появляются унаследованные неявные vPtr1, vPtr2 и т.п., каждый со своим смещением. И такая сложная структура ещё никому не мешала делать COM-объекты на C++.

Как устроены классы и где там хранятся указатели на VMT интерфейсов, я не знаю. Но вы можете попробовать связаться с Инной Аринович (модератор Круглого стола), она когда-то давно детально разбиралась с этим, может, вспомнит.


 
Ins ©   (2008-02-05 14:14) [10]


> clickmaker ©   (05.02.08 14:01) [8]


Для того, чтобы вызвать метод QueryInterface мало знать только VMTOFFSET IInterface.QueryInterface. Нужен еще и адрес самого интерфейса. Вопрос в том, был ли он раньше фиксированным и совпадал ли с адресом VMT класса?

Может есть у кого-нибудь system.pas, где vmtQueryInterface еще не deprecated?


 
Ins ©   (2008-02-05 14:29) [11]


> Как устроены классы и где там хранятся указатели на VMT
> интерфейсов, я не знаю.

Ну я с этим вроде пробовал разбираться, эксперименты на D7 и выше показали, что VMT для класса хранится по смещению 0 в экземпляре всегда. Но каждый интерфейс, который класс реализует, также добавляет в экземпляр неявные поля - ссылки на свои VMT. И они располагаются по некоторым смещениям от начала объекта в памяти. Эти смещения можно узнать из структуры TInterfaceEntry (поле IOffset), да не суть.
Т.е. например, для объекта TA(TSomeClass, IInterface, IA) внутреннее устройство может быть таким:
0: Указатель на VMT класса TA
4. Некое поле объекта, объявленное еще в классе TSomeClass
8. Указатель на VMT интерфейса IInterface
12. Указатель на VMT интерфейса IA
Т.е. каждый новый интерфейс (IInterface в том числе) добавляет к объекту 4 байта - указатель на VMT этого интерфейса. Тут ситуация та же, что и с множественным наследованием в C++ - каждый новый предок (интерфейсного типа) добавляет после полей предка указатель на свой VMT. Но так реализовано в D7 и выше. Объявления vmtQueryInterface и прочие говорят о том, что раньше указатель на VMT класса автоматически был указателем на VMT интерфейса IUnknown. Похоже с тех пор это в объектной модели изменилось, но хотелось бы знать точно.


 
Ins ©   (2008-02-05 14:33) [12]


> Фраза "структура COM-объектов строго стандартизована" неправильная.
>  До структуры COM-объекта вообще дела никому нет. Единственное
> требование к нему - чтобы он умел возвращать указатели на
> интерфейсы

Я тоже к этому склонялся, а раз так - то это многое объясняет.


 
kami   (2008-02-05 14:50) [13]

Ins ©   (05.02.08 14:14) [10]
Может есть у кого-нибудь system.pas, где vmtQueryInterface еще не deprecated


Есть от D5.


 
Ins ©   (2008-02-05 14:51) [14]


> Есть от D5.

Там  vmtQueryInterface как deprecated объявлено?


 
Kolan ©   (2008-02-05 15:16) [15]

>
> Там  vmtQueryInterface как deprecated объявлено?

Delphi 5:
 vmtQueryInterface    = 0;
 vmtAddRef            = 4;
 vmtRelease           = 8;
 vmtCreateObject      = 12;


DDS 2006:
 vmtSafeCallException = —32 deprecated;  // don’t use these constants.
 vmtAfterConstruction = —28 deprecated;  // use VMTOFFSET in asm code instead
 vmtBeforeDestruction = —24 deprecated;
 vmtDispatch          = —20 deprecated;
 vmtDefaultHandler    = —16 deprecated;
 vmtNewInstance       = —12 deprecated;
 vmtFreeInstance      = —8 deprecated;
 vmtDestroy           = —4 deprecated;

 vmtQueryInterface    = 0 deprecated;
 vmtAddRef            = 4 deprecated;
 vmtRelease           = 8 deprecated;
 vmtCreateObject      = 12 deprecated;


 
Ins ©   (2008-02-05 15:19) [16]

О! Тогда если можно - скиньте сюда, пожалуйста:

randr_insСОБАКАserverТОЧКАby


 
Kolan ©   (2008-02-05 15:23) [17]

Ушло


 
Asker   (2008-02-05 15:29) [18]

какой кошмар
Автор, Вам больше нечем заняться?
внутренняя реализация классовой ссылке сделана с учётом совместимости с технологией COM
ВСЁ - больше ничего знать не надо


 
Ins ©   (2008-02-05 15:30) [19]

Пришло, спасибо. Дома его препарирую :) В принципе, это + ответ Антона про "неверное утверждение" - вполне исчерпывающее решение. Всем спасибо!


 
Ins ©   (2008-02-05 15:31) [20]


> ВСЁ - больше ничего знать не надо

Да вообще много знать вредно, говорят на сон плохо влияет ;-)



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

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

Наверх





Память: 0.51 MB
Время: 0.011 c
8-1177042797
Dmitriy_O.
2007-04-20 08:19
2008.03.16
Как сделать "вспышку" тоесть чтобы картинка засветилась яркими цв


9-1168345585
HPR
2007-01-09 15:26
2008.03.16
[порка] Rhоmbis


3-1193483771
TheEd
2007-10-27 15:16
2008.03.16
Оптимизация сетевого траффика


2-1203459331
Богдан
2008-02-20 01:15
2008.03.16
Как перетащить файл из ПРОГРАМЫ в ПАПКУ


2-1203493310
Dasting
2008-02-20 10:41
2008.03.16
Директива out





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