com深入理解(下)
本文上篇已经说明了类对象实际是一个结构实例,并且为了实现进程间传递类对象指针以达到引用的目的,需要为此类专门编写一个代理类,并在传递时例示(即实例化)其一个对象以实现代理对象.而此代理类必定分成两部分,即一部分的成员函数专门在客户进程被调用,另一部分专门在组件进程被调用以实现进程间的数据传递进而将客户的调用命令原封不动地传递给组件对象以实现客户操作组件对象. 【程序编程相关:如何利用VC的Remote Debug功】
——方法参数类型为cruntimeclass*.void*等 【推荐阅读:ASP.NET中的MVC模式应用】
为了在客户端生成一个代理对象,必须将某些信息传递过去,然后在客户端根据传递的信息构建一个代理对象.在idl语言的类型定义中,没有类这种类型,因此是不可能让接口方法的参数类型为某个自定义类的指针.但是的确有此需要,则只能将类对象指针转成某种idl中识别的类型,最好的候选人就是void*,然后借助midl生成的代码将构建代理对象的信息传递过去. 【扩展信息:用IMAPI实现CD刻录和设备查找】
上面的做法实际就是编写自定义汇集操作时应该干的事,只不过还需照着com的几个附加规定来做,如必须实现imarshal接口等.本文说明如何为这样的类型传递编写标准的代理/占位组件以跨进程传递类对象的指针(使用midl来完成). void*不带有任何语义,其仅表示一个地址,因此在idl中传递void*是错误的,因为midl无法根据void*所带的语义确定应该如何汇集其指向内存中的内容.但是midl还是提供了多种途径来解决这个问题的,下面仅说明其中两个用得最多的方法:[call_as()]属性与[wire_marshal()]属性. [local]与[call_as()] [local] 接口或接口方法都可以加上[local]属性以表示此方法或此接口中的方法不需要生成汇集代码,进而就避免了上面由于void*不带有任何语义而不能汇集其指向内容这个问题,因为不需要生成汇集代码,进而其所修饰的方法的参数可以为void*.此属性所修饰的方法或接口被称为本地方法或本地接口,因为这些方法没有汇集代码,不能进行远程调用.这在com的标准接口中应用十分广泛.如查看iunknown的idl代码,其就是一个本地接口.... 下一页