组件技术的本质COM实例分析一

COM编程

进程内COM服务器(In-Process COM Server)

进程内的COM服务器(In-Process Com Server)在这前已经简单的介绍过,在此,只对一些需要明白、理解的知识点进行阐述,再进行编程可能会更好一点;进程内服务器是由于它们在DLL内实现而获得这个名称的。因此,服务器占擗了和使用它的应用程序一样的地址空间(进程)。所有的进程内COM服务器输出四个标准函数:DllRegisterServer、DllUnregisterServer、DllGetClassObject和DllCanUnloadNow。根据字面意思,我们也已经可以感觉的出这些函数的工作都会是什么。当然,Delphi已经为我们提供了这些函数的缺省实现。因此,读者不必自己写代码来实现这些函数,但应该理解他们具体是做什么的。

² DllRegisterServer。DllRegisterServer以两种方式自动调用。IDE的Register ActiveX Server菜单选项调用它,Windows的命令行应用程序RegSvr32.exe(或者Borland应用程序TRegSvr)也会调用它,很多情况下可以直接用Register ActiveX Server去调用,如果手动的去实现,可以写一个.Bat文件。无论通过那种方式调用它,DllRegisterServer用Windows注册表来注册COM对象。

² DllUnregisterServer。可以感觉的出来,这个函数和DllRegisterServer是作相反的工作,实际上它们就是一个相逆的过程,它移走了DllRegisterServer放在Windows注册表中的所有条目。可以用IDE里的 UnRegister ActiveX Server来调用这个工程。

² DllGetClassObject。DllGetClassObject负责提供给COM一个类厂,该类厂用于创建一个COM对象(在讨论类厂的时候,我们也做过明确的说明)。

² DllCanUnloadNow。COM负责调用DllCanUnLoadNow来看是否可以从内存中卸载COM服务器。

线程支持(Threading Support)

线程支持只适合于进程内服务器,并且不适用于进程外服务器。进程内服务器可以附着在几个的一个。进程内服务器的线程模型被存在Windows注册表中,具体如下:

² ……

² ……

² ……

² ……

…………

注册服务器(Registering the Server)

此处将不再重提如何注册服务器,只是简单的说一说为什么要进行注册。我们都知道,普通的Dll也需要进行注册才可以运行,而COM对象或是COM服务器要提供给服务于Client,那么客户端首先要知道要没有这个服务?如何进行这个服务的调用或是访问,因此它会找一些有用的键值,而客户所找的范畴就是注册表。由此而言,注册的确很有必要而肯是必不可少的。

构造函数

应该明确的是,做为一个提供服务的对象或接口或是一个组件,有一步工作应该提前做,那就是构造,而构造也是初始化,并且之前我们也说过,COM对象最好派生于TcomObject类,如此一来,我们就不得不去考虑在TcomObject中定义的构造函数都调用了虚方法函数Initialize。如果需要为自己的COM对象提供初化代码,只需要重载Initialize方法,定义如下:

Procedure Initialize ;Virtual;

将初始化代码放在Initialize中而不是构造函数中的原因是:Delphi中的COM对象的基类包含了一系列的非虚构造函数。根擗需要,类厂奖在不同的实例中调用不同的构造函数。而Initialize是虚方法,并且是唯一可以在调用时不考虑哪个构造函数是用于创建COM对象的方法。

创建一个进程内COM对象的实例

当用户需要在自己的客户程序代码中创建一个COM对象,一般会调用CreateConObject函数,该函数在ComObj.pas中定义,声明如下:

Function CreateComObject(const ClassID:TGUID):IunKnown;

CreateComObject将要创建的COM对象的GUID作为一个参数,并返回该COM对象的IunKnown指针。苦所请求的GUID在Windows注册表中找不到的话,将会抛出一个异常。那么我们一起来分析一下CreateComObject函数的实现如下:

function CreateComObject(const ClassID: TGUID): IUnknown;

begin

OleCheck(CoCreateInstance(ClassID, nil, CLSCTX_INPROC_SERVER or

CLSCTX_LOCAL_SERVER, IUnknown, Result));

end;

之前我们曾讨论过OleCheck,现在将重点的精力放在CoCreateInstance上边。如果根踪CoCreateInstance会发现如下信息:

function CoCreateInstance; external ole32 name 'CoCreateInstance';

因此可以这样认为,CreateComObject函数所作的只是调用了一下Windows的函数CoCreateInstance,并提供了一些默认的参数

CoCreateInstance主要有五个参数:

Clsid:Clsid是我们想要创建的COM服务器的GUID。这是我们专们传递给CreateComObject唯一的一个参数。

UnkOuter:只有在此COM对象是集合的一部分时才使用它。

DwClsContext:dwClsContext决定了读者想要创建的类型。CreateCOMObject自动要求创建一个进程内服务器(CLSCTX_INPROC_SERVER)或本地的进程外服务器(CLSCTX_LOCAL_SERVER)。有时与此函数一起使用的另外一个标记是CLSCTX_REMOTE_SERVER。此标志在DCOM中使用,以后将会讨论。

Iid:iid是我们想要获取一个对它的引用的接口。Delphi通常需要对IunKnown接口的应用,因为如果要其它别的引用的话,大多数类厂会失败。Microsoft用此参数主要是为了将来的扩展。

Pv:主要是得到IunKnown接口的指针。

{一个需要注册的是:CoCreateInstance内部创建负责创建COM对象类厂的实例,然后使用类厂来创建对象。创建完COM对象之后,类厂就被销毁。显然,如果要创建相同COM对象的多个实例,这不是非常有效的,在这种情况下就要自大闯将一个类厂的实例,并在删除它之前使用它的CreateInstance方法来创建COM对象。}

正如以前提到的,CreateComObject通常返回一个IunKnown指针。要获取需要的接口针,应使用as操作符,如:

MyIntf := CreateCOmObject(CLSID_MyServer) as IMyInterface

实例:一个简单的COM应用程序

在讨论了COM服务器的一些基本概念之后,我们用一个简单的小实例来说明如何调用以DLL形式提供服务的COM服务器,之后,我们会对此COM服务器进行扩展,并且会再给一个COM服务器的高级编程,但一切需要一步一步的来。

实例说明:

此实例是当正确登录到COM服务器时,就可以实现一个简单的算法,此处没有给出COM服务器与数据库服务器之间的连接,所以登录不是一个动态的从数据库用户信息表里进行判断,而是在程序中指定了一个固定的用户名,当然,在此处,可以连接一些文本数据库来进行动态的判断。此处的算法很简单,就是传统的小猴子吃桃子的问题,一个小猴子有一些桃子,每天吃一半,因为嘴馋,又多吃一个,这样每天就是吃一半多一个,当到了第十天时,吃完之后仅仅有一个了(此处的吃完仍然是吃了一半多一个),而算法就是要知道小猴子子本来要多少只桃子。

问题分析:因为需要用到COM服务器的一些方法,所以可以暂时作如下的决定:

用户的信息判断,即登录是否成功让服务器来为我们判断,客户端仅仅是作简单的错误性检查和数据的提交,正真的实现一个瘦客户端;

{说明:此处所说的瘦客户端希望读者朋友们不要仅仅根据字面意思来看客户端,并非是客户端的代码越少越好,客户端所要作的工作都让服务器去做才是瘦。其实,不应该如此去理解,而我们一般理解的服务器/客户端应该是服务器帮客户端处理一些逻辑上的、业务上的分析,而一些判断性的错误可以由客户端去完成,虽然是客户端,但它同样有一些自身的检查在里边,虽然是服务器端,它仍有一些任务由客户端去完成,再更多的情况,也许对读者朋友来说,感觉可能让客户做的更好}

算法实际上很简单,可以利用循环,也可以利用递归,在此仅仅做简单的分析。我们用循环来处理的话应该需要从后边入手,第十天刚刚吃的还有一个桃子,那么第十天,就应该是四个,第九天是十个,第八天是二十二个……,如此类推,我们可以很容易的得出一共有多少个桃子,可以进行如下的处理:

Var

Acount : Integer;

Asum : Integer;

Begin

Asum := 1;

For Acount := 10 DownTo 1 do

Asum := ( Asum + 1 ) * 2;

End;

理解起来很容易,到了第十天吃过之后还剩一个桃子,那么,第

时间: 2024-10-26 00:14:20

组件技术的本质COM实例分析一的相关文章

PHP中常见的缓存技术实例分析_php技巧

本文实例分析了PHP中常见的缓存技术.分享给大家供大家参考.具体如下: JBLOG在开发的过程中,对性能的优化做了不少工作.为了尽量减少不必要的数据库查询,我对一些数据进行了缓存和静态化处理. 缓存的原理:把一些经常要用到但又很少改动的数据以数组或其它形式存储到一个独立的PHP文件中,然后在需要用到的时候包含进来. 缓存的优点:能够大大减少数据库的查询次数,减轻数据库的压力,提高程序的执行效率. JBLOG缓存的数据有:系统设置.博客分类.侧栏最新日志.最新评论.博客统计.日志归档.友情链接.标

巧用百度分词技术实例分析博客多个关键词的排名

武汉SEO混小子最近每天忙着做饭啊做饭.被做饭折腾的够呛,手上还有很多网站需要维护,所以博客一直不接单子做,找的人倒是挺多的,昨天就有一位广州的人加我QQ,咨询了下网站的事情,他也是位初入SEO的朋友,老板交给他一个网站,要在首页做8个关键词,因为每个关键词有的长有的短,结合起整体,就感觉非常长,或许效果不是很好,就来问到我,其实这样的问题我在以前也纠结过,不过还好,慢慢的使用实例就解决掉了,合理的运用百度分词技术可以达到这个目的,今天这篇文章就实例分析下我的这个博客,让新手朋友直观的了解下百度

JavaScript事件委托技术实例分析_javascript技巧

本文实例分析了JavaScript事件委托技术.分享给大家供大家参考.具体分析如下: 如果一个整体页面里有大量的按钮.我们就要为每一个按钮绑定事件处理程序.这样就会影响性能了. 首先每个函数都是对象,对象就会占用很多内存.内存中的对象越多,性能就越差. 其次,dom访问次数增多,就会导致延迟加载页面.事实上,从如何来利用好事件处理程序,还是有很好的解决方案的. 事件委托: 对事件处理程序过多的问题解决的方案就是事件委托技术. 事件委托技术利用了事件冒泡.只需指定一个事件处理程序. 我们可以为某个

Javascript闭包用法实例分析_javascript技巧

本文实例分析了Javascript闭包的概念及用法.分享给大家供大家参考.具体如下: 提到闭包,想必大家都早有耳闻,下面说下我的简单理解. 说实话平时工作中实际手动写闭包的场景并不多,但是项目中用到的第三方框架和组件或多或少用到了闭包. 所以,了解闭包是非常必要的.呵呵... 一.什么是闭包 简而言之,就是能够读取其他函数内部变量的函数. 由于JS变量作用域的特性,外部不能访问内部变量,内部可以外部变量. 二.使用场景 1. 实现私有成员. 2. 保护命名空间,避免污染全局变量. 3. 缓存变量

中国人工智能学会通讯——机器人组件技术在智能制造系统中的应用

摘要:随着工业4.0时代的到来,如何将传统工厂改造成为个性化.网络化.柔性生产的智能制造系统成为了当前的研究热点.本文从智能制造系统和智能机器人系统的相似性出发,构建了基于机器人组件技术的智能制造系统,对智能制造系统中各个生产单元进行组件化技术封装,实现了生产组件之间的信息互联和即插即用,通过个性化订单要求对各生产组件在线任务规划,达到柔性生产的目标.此外用多异构机器人模拟各工位生产单位搭建了一个可以根据用户订单生产的小型智能制造实验平台,实验结果验证了本研究构建系统的可行性. 关键词:机器人组

Java 编程技术中汉字问题的分析及解决(转)

编程|汉字|解决|问题 Java 编程技术中汉字问题的分析及解决 段明辉自由撰稿人2000 年 11月 8日内容: 汉字编码的常识 Java 中文问题的初步认识 Java 中文问题的表层分析及处理 Java 中文问题的根源分析及解决 Java Servlet 中文问题的根源 修改 Servlet.jar 中文乱码的处理函数 参考资料 作者简介在基于 Java 语言的编程中,我们经常碰到汉字的处理及显示的问题.一大堆看不懂的乱码肯定不是我们愿意看到的显示效果,怎样才能够让那些汉字正确显示呢?Jav

搜索引擎优化回归本质关于链接分析

  上周周六在A5跟大家分享了"2013年搜索引擎优化全新的蜕化"关于网站内容,主要是针对最近搜索引擎的调整,让站长能够找准自己的所在位置,自己针对产品的用户群的内容方面知识,今天来跟大家分享下"2013年搜索引擎优化全新的蜕化"链接篇. 很久之前做优化的都知道,seo圈子里面有这么一句话"内容为王.外链为皇"这句话盛世流传,一直是seoer的终极目标,但是搜索引擎优化腾空出世的几年中,到底有多少人真正做到了这两点.内容和链接的结合密不可分,这节

Java 编程技术中汉字问题的分析及解决(转自IBM)

编程|汉字|解决|问题 Java 编程技术中汉字问题的分析及解决 段明辉自由撰稿人2000 年 11月 8日 在基于 Java 语言的编程中,我们经常碰到汉字的处理及显示的问题.一大堆看不懂的乱码肯定不是我们愿意看到的显示效果,怎样才能够让那些汉字正确显示呢?Java 语言默认的编码方式是UNICODE ,而我们中国人通常使用的文件和数据库都是基于 GB2312 或者 BIG5 等方式编码的,怎样才能够恰当地选择汉字编码方式并正确地处理汉字的编码呢?本文将从汉字编码的常识入手,结合 Java 编

javascript原始值和对象引用实例分析

javascript原始值和对象引用实例分析         这篇文章主要介绍了javascript原始值和对象引用的方法,实例分析了javascript原始值和对象引用的功能.定义与相关技巧,需要的朋友可以参考下 本文实例讲述了javascript原始值和对象引用的方法.分享给大家供大家参考.具体分析如下: 一句话来说:原始值是不可变的,而对象引用是可变的. js中的原始值(undefined.null.布尔值.数字和字符串)与对象(包括数组和函数)有着本质的区别.原始值是不可更改的,任何方法