DCOM 揭秘之四

2008-04-09 04:02:22来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

  我们已经讨论了DCOM的基本要点,了解了如何创建一个简单的DCOM服务器和一个相关的客户端。你也可以看到这个基本的过程是非常简单的---ATL向导处理了服务器端的大部分细节,要激活服务器,你只需要在客户端写10行左右的代码就可以了。

  接下来我们将讨论两个相关的主题。首先是创建你自己的COM客户和服务器,结合第一部分我们所学到的,让你了解要在自己的代码中集成一个DCOM服务器,确实需要做哪些事情。然后我们将快速地看一下由ATL向导产生的代码。

  本文的最后将会讲解要创建一个分布式的COM服务器,你需要经过的步骤。所谓分布式的COM服务器,是指该服务器可以处在网络的别处,并且可通过网络非常简单和透明地激活。

  创建自己的COM客户和服务器

  在第一部分的DCOM介绍中,你可以看到要创建COM客户和服务器是非常简单的。只要在客户和服务器端写入几行代码就可以产生一个完整的COM应用。你现在明白到为什么许多的开发者在创建一个DLL时会使用COM了--因为仅需要大概5分钟,就可以设置好一个进程内的COM DLL,并且令它工作。

  本部分的目的是讨论如何创建自己的COM服务器,并且在你创建的真正应用中使用它们。你也会记得,第一部分介绍的客户端代码是非常少的。我们将介绍要创建服务器需要进行的基本步骤,然后看看要正确地激活服务器,你需要在客户端写入哪些代码。

  服务器端

  ATL向导令COM服务器的创建变得非常的简单。创建一个COM coclass的第一步是要分离出一个或者多个的功能函数,你要从一个应用的代码主体中分离出这些功能函数。至于分离出来的目的,可以是多样的,你可能是想让该函数可以跨越多个应用重新使用,也可能是让一个队伍的编程者更容易地分离出各个独立的工作组,或者是让代码的开发和维护变得更加的简单。不论是出于什么原因,定义功能是第一步。

  有一点可能令定义这些边界变得更为简单,这就是COM服务器的运作和一个普通的C 类是几乎一样的。象一个类,你实例化一个COM类,然后可以开始调用它的方法。COM的实例化和方法调用的句法和C 是有点不同的,不过它们的想法是一样的。如果一个服务器仅有一个接口,它事实上的用法就相当于一个类。(不过在访问对象时,你仍然需要遵守COM的规定)

  一旦你已经定义了功能和访问它的方法,就可以建立自己的服务器。在第一部分中,我们已经知道,要创建一个服务器,有4个基本的步骤:

  1。使用ATL向导来创建你的COM服务器的外壳。你选择该服务器是一个DLL、一个EXE或者是一个服务。

  2。在服务器的外壳中创建一个新的COM对象。你将要选择线程的模式,这将会创建可装入方法的接口。

  3。在你的对象中加入方法,并且声明它们的参数

  4。为你的方法写代码

  上面的这些步骤已经在第一部分中的“理解一个简单的COM服务器”中详细介绍过了。

  经过第一部分的介绍后,一个常见的问题是关于线程模式,也就是COM对象的独立线程(apartment-threade)和自由线程(free-threaded)之间的区别?要理解它们之间的区别的最简单方法是将独立线程看成为单线程,而将自由线程想象为多线程。

  在独立线程中,多个服务器客户的方法调用在服务器端的COM对象中被串行化,也就是说,每个独立的方法调用完成后,才会开始下一个的方法调用。因此独立线程的COM对象天生就是线程安全的,而自由线程的COM对象可同时在COM对象上有多个的方法调用执行。每个客户的方法调用都在一个不同的线程中运行。因此,在一个自由线程的COM对象中,你必须要注意多线程的问题,例如同步。

  开始的时候你将更趋向于使用独立的线程,因为它更加简单,不过以后最好转向到自由线程,因为它有着更多的优点。
  客户端

  第一部分介绍的客户端程序非常清楚和紧凑。不过,它包含很少的错误检测代码,因此要在一个真正的程序中应用是不足够的。让我们再次看一下这些代码,它非常简单,因此可让你清楚地看到要创建一个客户端的必要步骤。

void main()
{
HRESULT hr; // COM error code
IBeepDllObj *IBeep; // pointer to interface

hr = CoInitialize(0); // initialize COM
if (SUCCEEDED(hr)) // macro to check for success
{
hr = CoCreateInstance(
clsid, // COM class id
NULL, // outer unknown
CLSCTX_INPROC_SERVER, // server INFO
iid, // interface id
(void**)&IBeep ); // pointer to interface

if (SUCCEEDED(hr))
{
hr = IBeep-Beep(800); // call method
hr = IBeep-Release(); // release interface
}
CoUninitialize(); // close COM
}


  CoInitialize和CoCreateInstance的调用初始化COM,并且得到指向一个接口的指针。然后你就可以调用接口的方法。在完成方法调用后,你就可释放接口并且调用CoUninitialize。整个步骤就完成了。

  不过,在一个COM客户尝试启动一个COM服务器时,可出现各种不同的错误。一些常见的问题包括有:

  . 客户端不能启动COM

  . 客户端不能查找到请求的服务器

  . 客户端能查找到请求的服务器,但是不能正确地启动

  . 客户端不能找到请求的接口

  . 客户端不能找到请求的方法

  . 客户端可以找到请求的方法,但在调用时失败

  . 客户端不能正确地清除

  为了跟踪这些潜在的问题,你必须在每一步作检查,具体是查看HRESULT的值。以上的代码有作检查,不过在出错的时候并没提示。以下的函数补救了这个不足:

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:基于请求代理的中间件模型

下一篇:DCOM揭秘之五