您的位置:首页 > 编程语言 > C#

在C#中使用COM的一些随想---转载的

2005-08-20 21:25 411 查看
在C/C++的世界里,操作COM的时候是指针满天飞. 而在C#里,除非我们刻意编写unsafe code,否则一般是见不到指针的.
但其实在C#里使用COM组件相对C++来说,是方便多了.  使用TlbImport工具可以生成对COM组件的C#封装, 如果在IDE里import一个COM组件,甚至这一切都是透明地自动完成的. 而使用过程中,C#也向程序员提供了更friendly的方法. 比如:
1. refCount我们当然已经不需要去理会
2.不需coCreateInstance()调用,直接用new产生COM对象的实例.
3. connection-point现在对应于C#的event.
4.通过接口A查询接口B,直接用强制转换的语法形式即可. 例如
    IHTMLDocument2 ihdoc = new HTMLDocumentClass();
    IMarkupPointer iMP = (IMarkupPointer)ihdoc;
只要通过IHTMLDocument2能查询到IMarkupPointer接口,我们就可以用这种形式的代码来获取IMarkupPointer接口. 虽然后台肯定调用了QueryInterface,但C#程序员已经不需要去关心这些了. 当然,如果接口查询失败,会抛出转型错误的异常.
 
  不过这种语法的背后机制倒是让我想起了C++里面一些有趣的东西.
通常来说对一个指针转型动作(cast)只是转换了该指针的类型,而指针的值是不变的.
例如
int *p = (int *)pClass;
执行之后, p和pClass是指向同一个内存地址的.
但有一种比较少见情况,转型之后不但类型变了,连指针的值都会改变.
假如类A继承了一个以上的虚拟基类:
class A : public vBase1,vBase2
{
 // ...
};
那么在下面代码执行之后
vBase1 *p1 = (vBase1*)pA;
vBase2 *p2 = (vBase2*)pA;
 p1和p2会分别指向不同的内存地址. 这是因为类实际上合并了vBase1和vBase2的虚函数表(vTable),拥有不止一个的vTable.
做了强制类型转换之后,要保证p1和p2能够分别指向正常的vBase1和vBase2,
必须分别返回不同的内存地址(保证p1和p2指向的内存仍然是一个完整的vBase1或vBase2对象)
以上在现实应用中最常见的例子,可能就是ATL了. 回头看看, 除了ATL之外, C++社区真的很少见到能够成功在工业界应用的广泛(是否真的广泛?hmm...)使用多重继承的类库(或者是我见识太少,^_^...)  COM本身并不支持MI,但是并不妨碍ATL用MI的方式来实现多个COM接口. 现在看来, 使用ATL的时候加上强制转型获得一个interface,和C#现在这种语法别无二致....从编写COM的CLIENT的角度来看,两者都摆脱了C里面对COM那种无比繁琐的操作方式, 只是C#对COM的细节隐藏得更好. 而对于开发COM的组件来说,由于引入了属性编程,C#是大幅抛离了C++. 自己编辑IDL文件现在看来就如同原始的手工业,是那么的遥远...
如果C#能早点出生,或许COM就不会落到现在这种地步... ^_^

http://www.juntuan.net/hkbc/winbc/n/2005-07-04/6090.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息