gpt4 book ai didi

c++ - 为什么 COM(组件对象模型)语言无关?

转载 作者:可可西里 更新时间:2023-11-01 18:18:11 26 4
gpt4 key购买 nike

我知道 COM 提供跨语言和应用程序的二进制级别的可重用性。我读到所有为 COM 构建的组件都必须遵守标准内存布局才能独立于语言。

我不明白“标准内存布局”是什么意思。

什么使 COM 语言独立?

最佳答案

首先,一些技术背景:C++ 编译器通常会为任何具有虚函数的类生成一个称为“vtable”的东西。这基本上是一个函数指针表。 vtable 包含指向类实现的每个虚方法的函数指针。

在 COM 中,接口(interface)基本上是组件实现的抽象基类,例如:

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

CSomeComponent 的 vtable 将包含这两个接口(interface)中定义的所有方法的函数指针。

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)();
...
};

任何实例化的对象都有对其动态类型的 vtable 的引用。这就是程序如何知道在派生类中重写基方法的情况下如何调用正确的方法:

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 具有对类 Derived 的 vtable 的引用。如前所述,vtable 就像一个函数指针列表。现在,vtable 有一个固定的布局:如果 Derived 类继承自 Base 类,方法 foo 的函数指针将位于相同的相对位置在 Derived 的 vtable 中比在 Base 的 vtable 中:

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 对应于 vtable 中的第一个条目。因此它发出对第一个函数指针的调用,在 X 的情况下是对 Derived::foo 的调用。

对您的问题的回答:编译器只能生成 COM 组件,如果它们为 COM 规范要求的 vtables 生成相同的布局。 vtables 可以用各种不同的方式实现,尤其是涉及多重继承时(COM 组件需要)。遵守特定的 vtable 格式是必要的,这样当您调用组件的方法 f 时,您实际上会调用方法 f 而不是其他方法g 恰好位于组件类的 vtable 中 f 的位置。我认为 COM 兼容的编译器本质上必须生成与 Microsoft Visual C++ 相同的 vtable 布局,因为 COM 技术是由 Microsoft 定义的。

P.S.:抱歉技术性太强,希望以上信息对您有所帮助。

关于c++ - 为什么 COM(组件对象模型)语言无关?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2032939/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com