Почему COM (Объектная модель компонентов) независим от языка?

Я знаю, что COM обеспечивает возможность многократного использования на двоичном уровне через языки и приложения. Я считал, что все компоненты, созданные для COM, должны придерживаться стандартного расположения памяти, чтобы быть независимыми от языка.

Я не понимаю то, что "означает стандартное расположение памяти".

Что делает COM независимый от языка?

7
задан stakx supports GoFundMonica 24 June 2012 в 18:44
поделиться

4 ответа

Во-первых, некоторая техническая подготовка : Компиляторы Си++ обычно генерируют нечто, называемое "vtable" для любого класса с виртуальными функциями. В основном это таблица указателей на функции. Таблица содержит указатель функции на каждый виртуальный метод, реализованный классом.

В COM интерфейсах в основном представлены абстрактные базовые классы, которые реализует компонент, например:

class CSomeComponent : IUnknown, ISomeOtherInterface  { ... };

В vtable для CSomeComponent будут включены указатели функций для всех методов, определенных в этих двух интерфейсах.

struct __imaginary_vtable_for_CSomeComponent
{
    // methods required by IUnknown
    HRESULT (*QueryInterface)( const IID& iid, void** ppv );
    ULONG (*AddRef)();
    ULONG (*Release)();
    // methods required by ISomeOtherInterface
    void (*foo)();
    ...
};

Любой инстанцированный объект имеет ссылку на переменную своего динамического типа. Таким образом, программа знает, как вызвать соответствующий метод в случае переопределения базового метода в производном классе:

class Base
{
public:
    virtual void foo() { ... }
}

class Derived : public Base
{
public:
    virtual void foo() { ... }  // overrides Base::foo()
    virtual void bar() { ... }
}

...

Base* X = new Derived;
X->foo();

Последняя строка должна вызывать Derived::foo. Это работает, так как объект X имеет ссылку на vtable for класса Derived. Как уже говорилось, эта переменная похожа на список указателей функции. Теперь, vtable имеет фиксированную компоновку: Если класс Derived наследует от класса Base, то указатель функции для метода foo будет находиться в том же относительном местоположении в переменной Derived, что и в переменной Base:

struct __imaginary_vtable_for_Base
{
    void (*foo)();
};

// __imaginary_vtable_for_Base::foo = Base::foo

struct __imaginary_vtable_for_Derived
{
    void (*foo)();
    void (*bar)();
};

// __imaginary_vtable_for_Derived::foo = Derived::foo

Теперь, если компилятор видит что-то вроде X->foo(), он знает, что для всех классов, полученных из Base, метод foo соответствует первой записи в таблетке. Поэтому он производит вызов первого указателя функции, который в случае X является вызовом к Derived::foo.

Ответ на вопрос : Компиляторы могут генерировать COM компоненты только в том случае, если они генерируют ту же самую компоновку для таблиц, которую требует спецификация COM. Таблицы могут быть реализованы различными способами, особенно когда речь идет о множественном наследовании (что требуется для COM-компонентов). Соблюдение определённого vtable-формата необходимо для того, чтобы при вызове метода компонента f фактически вызывался метод f, а не какой-то другой метод g, который случайно окажется на позиции f в vtable класса компонента. Полагаю, что COM-совместимые компиляторы, по сути, должны выдавать те же векторные компоновки, что и Microsoft Visual C++, так как технология COM была определена компанией Microsoft.

P.S. : Извините, что я настолько технический, надеюсь, что приведенная выше информация будет вам полезна.

11
ответ дан 6 December 2019 в 14:04
поделиться
[

] Дон Бокс написал отличное объяснение в первой главе своей книги Essential COM. Вы можете прочитать его [] здесь [] бесплатно. Я рекомендую. [

]
4
ответ дан 6 December 2019 в 14:04
поделиться

Стандартный макет памяти означает макет памяти, который определен (стандартизирован) в спецификации COM, а не тот, который по умолчанию используется вызывающим или определяющим языком. И именно такие вещи делают его независимым от языка! Код на определенном языке, вызывающий COM-объект, не должен заботиться о том, на каком языке был написан этот COM-объект, с точки зрения знания его структуры в памяти.

0
ответ дан 6 December 2019 в 14:04
поделиться

Насколько я помню, COM - это язык, не зависящий от того, как документируется и открывается его структура (?). Недостатком является то, что структура является "бинарной" и тесно связана с Си/Си++, что затрудняет ее использование из других языков. Хорошая новость заключается в том, что многие языки (например, Python) имеют интерфейс C/C++, что позволяет (модуль Python Win32com) использовать его из других языков.

JSON является языком независимым таким образом, что не привязывается непосредственно к какому-либо языку, хотя Python, Perl и Ruby (?) близки, но почти невозможно использовать из C/C++

Надеюсь, это имеет какой-то смысл

.
0
ответ дан 6 December 2019 в 14:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: