📄 205003.htm
字号:
<html><body><span id=Layer1><a name=205003><font color=#3e70d7 face=arial size=5><b>Marshaling</span><span id=Layer2></b></font><p><font size=2 color=#3c3c3c face=arial>思考一下,当一个客户端呼叫COM物件的method时会发生何事?再者,客户端与物件可能在不同的apartment、行程或机器上(现在在COM+中则在不同的context)。若要解决这个问题,呼叫COM物件上的method通常需要某些中介者将呼叫的参数包装成标准格式,这个过程称作marshaling。这些被包装的参数接着便经由某些适当的机制跨边界传送,不管跨何边界,这将把客户端与物件分开。一旦传送到目的,被呼叫的物件必须将参数的包装解开,将它们由标准的格式转换成物件可以处理的格式。</span><span id=Layer3></font></p><p><font size=2 color=#3c3c3c face=arial>呼叫method通常需要进行marshaling与unmarshaling</span><span id=Layer4></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>呼叫method通常需要进行marshaling与unmarshaling</span><span id=Layer5></font></p><hr><p><font size=2 color=#3c3c3c face=arial>COM提供两个基本的方案以进行marshaling。第一个,称为标准的marshaling,依赖proxy与stub,程式得善用型态程式库。第二个选项,自订的marshaling,同样也使用proxy与stub,但给程式设计师较大的弹性。这两个方案各有优缺点,在今日也都被使用。</span><span id=Layer6></font></p><p><font size=2 color=#3c3c3c face=arial>COM提供两种marshaling类型</span><span id=Layer7></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>COM提供两种marshaling类型</span><span id=Layer8></font></p><hr><font color=#3e72d7 face=arial size=4><b>标准Marshaling</span><span id=Layer9></b></font><p><font size=2 color=#3c3c3c face=arial>为了要了解marshaling,先想想一个介面真正定义的东西是什麽。其实就是一堆method,每一个method都拥有一个名字,或许有一或多个参数。这些参数必须以定义的顺序出现,每一个参数都有自己的资料型态。若要正确地包装一个method的呼叫,须要了解method参数的类型,以及它们出现的顺序。同样地,反包装需要知道相同的资讯,以得知收到的东西为何,才能正确地呼叫这个method。问题是,接下来得取得一对适当的proxy/stub,然後提供proxy与stub需要的资讯。在为Windows 2000撰写的COM应用程式中,最常用的方式便是使用系统提供的一对proxy/stub,它们有时也被称为是Universal marshaler。若要取得包装呼叫与反包装时所需的资讯,proxy与stub都得依赖於型态程式库。</span><span id=Layer10></font></p><p><font size=2 color=#3c3c3c face=arial>Marshaling需要method以及method的参数等资讯</span><span id=Layer11></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>Marshaling需要method以及method的参数等资讯</span><span id=Layer12></font></p><hr><p><font size=2 color=#3c3c3c face=arial>型态程式库通常被称做为typelib,包含机器可读取的资讯描述特定COM类别支援的介面。这些资讯可以储存在它自己的档案中,根据命名原则这个档案的副档名是.tlb;或者这些资讯也可以放到它描述的COM类别程式码所在的同一个档案中。不管如何完成这个动作,型态程式库中的资讯基本上和包含在此类别介面的IDL定义一致(若存在IDL的话)。最大的不同点是IDL档案是文字,可让人以及工具软体读取,如MIDL编译器。相比之下,型态程式库是由程式读取的。</span><span id=Layer13></font></p><p><font size=2 color=#3c3c3c face=arial>型态程式库储存类别以及它们介面的资讯</span><span id=Layer14></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>型态程式库储存类别以及它们介面的资讯</span><span id=Layer15></font></p><hr><p><font size=2 color=#3c3c3c face=arial>型态程式库可以由开发环境产生,如Visual Basic,或MIDL编译器。一旦型态程式库存在後,便可以用在许多事情上。举例来说,一个Visual Basic程式设计师可以浏览他的机器,检视任一个安装的COM类别提供的功能。可以这麽做的缘故事实上是存取了这些类别的型态程式库。然而还有一种常用的方式以进行marshaling。图5-7显示typelib驱动的marshaling运作的情形。当一个客户端呼叫某个介面上的method,universal marshaler proxy便使用型态程式库中的资讯来判断如何正确地包装这个呼叫。被包装的参数将被转送到物件,在此universal marshaler stub便存取相同型态程式库的复本。然後使用这个资讯来反包装这个呼叫,接着呼叫目标物件上的method。universal marshaler不会为每个介面取得一对特定的proxy/stub,它是一个一般的服务,依赖型态程式库来执行它的函数。一旦类别的型态程式库安装并注册後,marshaling就可以运作。</span><span id=Layer16></font></p><p><font size=2 color=#3c3c3c face=arial>型态程式库可用作marshaling以及其它的目的上</span><span id=Layer17></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>型态程式库可用作marshaling以及其它的目的上</span><span id=Layer18></font></p><hr><br><center><a target=_new href=imagesh/5-7.gif><img border=0 src='imagesl/5-7.gif'></a></center></span><span id=Layer19><center><table border=0 ><td align=center><font color=#3c3c3c face=arial size=2><font size=2 face=arial color=#3e80d7><b> 图5-7</span><span id=Layer20> </b></font>Universal marshaler可使用型态程式库来取得包装呼叫与反包装时所需的资讯。</span><span id=Layer21></td></table></font></center><p><font size=2 color=#3c3c3c face=arial>执行marshaling时也有可能不会使用到型态程式库。将一个IDL档案,透过MIDL编译器编译後就会产生一对介面专属的proxy与stub,这两者可以在适当的系统上安装并注册,然後用来包装与反包装对那个介面上method的呼叫。Typelib驱动的marshaling一开始只支援dispinterface,同时比使用介面专属的proxy与stub要慢一些,这两个限制都已被克服了。这样的结果使得介面专属的proxy/stub较不常被使用。</span><span id=Layer22></font></p><p><font size=2 color=#3c3c3c face=arial>Marshaling也可由介面专属的一对proxy /stub来执行</span><span id=Layer23></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>Marshaling也可由介面专属的一对proxy /stub来执行</span><span id=Layer24></font></p><hr><font color=#3e72d7 face=arial size=4><b>自订Marshaling</span><span id=Layer25></b></font><p><font size=2 color=#3c3c3c face=arial>假设你需要做一些独一无二的事,或许是有特殊目的地进行marshaling。你可以做什麽呢?标准marshaling容易使用,不过它并没有为使用它的应用程式提供太大的弹性。COM的设计师预测到这个可能性。如有必要,COM程式设计师可以实作自订marshaling。这需要程式设计师实作标准的IMarshal介面。一旦完成这个动作,参数包装与反包装的动作便可以由程式设计师自订,并没有困难及快速的规则。</span><span id=Layer26></font></p><p><font size=2 color=#3c3c3c face=arial>自订marshaling允许程式设计师控制如何进行marshaling</span><span id=Layer27></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>自订marshaling允许程式设计师控制如何进行marshaling</span><span id=Layer28></font></p><hr><p><font size=2 color=#3c3c3c face=arial>举例来说,假设你希望将整个COM物件从一个行程传递另一个行程,或一台机器传递到另一台机器。达到这个目的的其中一种方式是粹取出物件所有的资料,然後以参数的型式将资料跨行程或机器边界传送至一或多个method呼叫。这些工作可以使用前面描述的标准marshaling机制完成。另一个解决方案则是使用自订marshaling马上将整个物件的资料移动。现在,传递一个介面指标到这个物件不仅仅传送指标,按标准情况,会移动物件所有的资料。有时称之为以值包装(marshal-by-value),这是使用自订包装的好范例。</span><span id=Layer29></font></p><p><font size=2 color=#3c3c3c face=arial>举例来说,自订marshaling可以以值传递物件,而不必以参考(refere-nce)传递</span><span id=Layer30></font></p><hr><font face=Arial Black color=#3e77d7 size=3><b></b></font><p><font size=2 color=#3c3c3c face=arial>举例来说,自订marshaling可以以值传递物件,而不必以参考(refere-nce)传递</span><span id=Layer31></font></p><hr><p><font size=2 color=#3c3c3c face=arial>除了它的复杂性之外,实作的责任并不是初学者的,自订marshaling还有一些缺点。举例来说,实作取消呼叫的功能还得需要额外的工作,而自订marshaling一般来说并不会和已设定元件一起使用。虽然自订marshaling并不常使用,但有时它确实提供某些特殊问题正确的解决方案。</span>
</body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -