C++ 为什么COM(组件对象模型)与语言无关?
我知道COM提供了跨语言和应用程序的二进制级别的可重用性。 我了解到,所有为COM构建的组件都必须遵循标准内存布局,才能独立于语言 我不明白“标准内存布局”是什么意思C++ 为什么COM(组件对象模型)与语言无关?,c++,com,C++,Com,我知道COM提供了跨语言和应用程序的二进制级别的可重用性。 我了解到,所有为COM构建的组件都必须遵循标准内存布局,才能独立于语言 我不明白“标准内存布局”是什么意思 什么使COM语言独立?标准内存布局是指COM规范中定义(标准化)的内存布局,而不是调用或定义语言使用的默认布局。正是这种东西使它独立于语言!调用COM对象的特定语言的代码不必关心COM对象是用什么语言编写的,只要知道它在内存中的结构。我记得COM是独立于语言的,因为它的结构是文档化和开放的(?)。缺点是这种结构是“二进制”的,并且
什么使COM语言独立?标准内存布局是指COM规范中定义(标准化)的内存布局,而不是调用或定义语言使用的默认布局。正是这种东西使它独立于语言!调用COM对象的特定语言的代码不必关心COM对象是用什么语言编写的,只要知道它在内存中的结构。我记得COM是独立于语言的,因为它的结构是文档化和开放的(?)。缺点是这种结构是“二进制”的,并且与C/C++紧密相连,这使得它很难从其他语言中使用。好消息是,许多语言(如Python)都有C/C++接口,这使得(Win32 COM Python模块)可以从其他语言使用 尽管Python、Perl和Ruby(?)非常接近,但JSON在某种程度上是独立于语言的,因此它不会直接映射到任何语言,但它几乎不可能从C/C中使用++
希望这有某种意义:
<强>第一,一些技术背景>:C++编译器通常为任何具有虚拟函数的类生成一个称为“VTABLE”的东西。这基本上是一个函数指针表。vtable包含一个指向类实现的每个虚拟方法的函数指针
在COM中,接口基本上是组件实现的抽象基类,例如:class CSomeComponent : IUnknown, ISomeOtherInterface { ... };
CSomeComponent
的vtable将包括这两个接口中定义的所有方法的函数指针
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();
最后一行应该调用派生::foo
。这是因为对象X
引用了类派生的vtable
。如上所述,vtable就像一个函数指针列表。现在,vtables有一个固定的布局:如果classDerived
继承自classBase
,那么方法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
的情况下,这是对派生::foo
的调用
回答您的问题:编译器只能生成COM组件,前提是它们生成的VTable布局与COM规范要求的布局相同。vtables可以以各种不同的方式实现,特别是当涉及到多重继承(COM组件需要多重继承)时。遵循特定的vtable格式是必要的,这样当您调用组件的方法f
时,您实际上将调用方法f
,而不是调用位于组件类vtable中f
位置的其他方法g
。我认为COM兼容编译器本质上必须产生与微软Visual C++相同的VTE布局,因为COM技术是由微软定义的。
p.S.:很抱歉这么专业,我希望以上信息对您有所帮助。唐·博克斯在他的书《Essential COM》的第一章中写了一个很好的解释。你可以免费阅读。我推荐它。-1因为声明的缺点是不正确的,因为比较COM和JSON就像比较一个引擎和一个包。好吧,是和否,我认为您可以将COM视为客户端访问“服务器”的传输接口,就像web服务一样。如果web服务是基于REST的,它通常会使用JSON。因此,在我看来,这种比较并没有那么牵强。。。。