COM(Component Object Model)是最近WIndows世界中最流行的TLA(three-letter acronym)。一些新技术的出现都是基于COM的。并且这些技术文档中抛出了很多术语,比如 「COM对象」 、 「接口」 、 「服务器」 等等,但都假设您已熟悉COM的基本工作原理和使用方法。
一、COM
COM(Component Object Model)是最近WIndows世界中最流行的TLA(three-letter acronym)。一些新技术的出现都是基于COM的。并且这些技术文档中抛出了很多术语,比如 「COM对象」 、 「接口」 、 「服务器」 等等,但都假设您已熟悉COM的基本工作原理和使用方法。
COM到底是什么
简单地说,COM是一种跨不同应用程序和语言共享二进制代码的方法。这与c++方法不同,后者促进了源代码的重用。ATL就是一个很好的例子。虽然源代码级重用可以很好地工作,但它只适用于c++。它还引入了名称冲突的可能性,更不用说在项目中拥有多个代码副本而导致的工程膨胀和臃肿。
Windows允许使用dll在二进制级别上共享代码。毕竟,这就是Windows应用程序的功能——重用kernel32.dll, user32.dll,等等。但是由于dll是写在C接口上的,所以它们只能由C或理解C调用约定的语言使用。这就把共享的重担放在了编程语言实现者身上,而不是DLL本身。
MFC通过MFC扩展dll引入了另一种二进制共享机制。但是这些限制更加严格——你只能从MFC应用程序中使用它们。
COM通过定义二进制标准解决了所有这些问题,这意味着COM指定二进制模块(dll和exe)必须被编译以匹配特定的结构。该标准还精确地指定了在内存中必须如何组织COM对象。二进制文件还必须不依赖于任何编程语言的任何特性(比如c++中的名称装饰)。一旦完成了这些,就可以很容易地从任何编程语言访问模块。二进制标准将兼容性的重担压在了生成二进制文件的编译器上,这使得以后需要使用这些二进制文件的人更加容易。
内存中COM对象的结构恰好使用与c++虚函数相同的结构,这就是为什么许多COM代码使用c++的原因。但是请记住,编写模块所用的语言是不相关的,因为生成的二进制文件可以被所有语言使用。
顺便说一句,COM不是特定于win32的。理论上,它可以移植到Unix或任何其他操作系统。然而,我似乎从来没有提到过COM以外的Windows世界。
使用COM对象
每种语言都有自己处理对象的方式。例如,在c++中,您可以在栈上创建它们,或者使用new动态地分配它们。因为COM必须是语言无关的,所以COM库提供了自己的对象管理例程。COM和c++对象管理的比较如下:
「创建一个对象」
- C++中,使用 「operator new」 或者在栈中创建一个对象
- COM中,调用COM库的API创建
「删除一个对象」
- C++中,使用 「operator delete」 或者栈中的对象作用域消失时,释放这个对象
- COM中,所有对象都保留自己的引用计数。调用者必须在调用者使用对象完成时告诉对象。当引用计数达到0时,COM对象从内存中释放自己。
由此可见,对象的创建和销毁这两个阶段缺一不可。当你创建一个COM对象时,你告诉COM库你需要什么接口。如果对象被成功创建,COM库返回一个指向所请求接口的指针。然后,您可以通过该指针调用方法,就像它是一个普通c++对象的指针一样。
延伸阅读:
二、dwFlags是什么
dwFlags确定Windows如何处理“复合”Unicode字符,即字母后跟变音符号。复合字符的一个例子是e。如果此字符位于代码页中指定的代码页中,则不会发生任何特殊情况。但是,如果它不在代码页中,Windows必须将其转换为其他内容。 传递WC_COMPOSITECHECK使API检查非映射的复合字符。传递WC_SEPCHARS使Windows将字符分成两个部分,字母后跟变音符号,例如e ‘。传递WC_DISCARDNS会使Windows放弃变音符号。传递WC_DEFAULTCHAR将使Windows用lpDefaultChar参数中指定的“默认”字符替换复合字符。默认行为是WC_SEPCHARS。