??xml version="1.0" encoding="utf-8" standalone="yes"?>久久国产免费观看精品,国产精品久久久久久久app,高清免费久久午夜精品http://www.shnenglu.com/suiaiguo/category/11213.html天行健,君子以自Z息; 地势坤,君子以厚徯?/description>zh-cnMon, 20 Jul 2009 17:16:00 GMTMon, 20 Jul 2009 17:16:00 GMT60COM技术入门基知识http://www.shnenglu.com/suiaiguo/archive/2009/07/17/90354.htmlSagaSagaFri, 17 Jul 2009 08:41:00 GMThttp://www.shnenglu.com/suiaiguo/archive/2009/07/17/90354.htmlhttp://www.shnenglu.com/suiaiguo/comments/90354.htmlhttp://www.shnenglu.com/suiaiguo/archive/2009/07/17/90354.html#Feedback6http://www.shnenglu.com/suiaiguo/comments/commentRss/90354.htmlhttp://www.shnenglu.com/suiaiguo/services/trackbacks/90354.html   q几天在学习COMlg技术,|上看了很多教程Q发现有一些很基础的东西基本都没有涉及Q下面我q合网上的一些教E加上自q体会来进行一些ȝ?br>
   (1)COMlg是什么?

   COMlg׃Win 32动态连接库QDLLQ或可执行文ӞEXEQŞ式发布的可执行代码所l成?/span>再向深入了看Q以C++ZQCOMlg实际上就是一些实C特定接口的类Q而接口都是纯虚类。组件从接口z而来。我们可以简单的用纯_的C++的语法Ş式来描述COM是个什么东西:

  class IObject
  
{
  
public:
    
virtual Function1(= 0;
    
virtual Function2(= 0;
    .
  }
;
  
class MyObject : public IObject
  
{
  
public:
    
virtual Function1(){}
    
virtual Function2(){}
.
  }

 
  看清楚了吗?IObject是我们常说的接口,MyObject是所谓的COMlg。切记切记接口都是纯虚类Q它所包含的函数都是纯虚函敎ͼ而且它没有成员变量。而COMlg是从这些纯虚类l承下来的派生类Q它实现了这些虚函数Q仅此而已。从上面也可以看出,COMlg是以 C++为基的,特别重要的是虚函数和多态性的概念QCOM中所有函数都是虚函数Q都必须通过虚函数表VTable来调用,q一Ҏ无比重要的,必需时刻牢记在心?br>
   (2) COMlg有三个最基本的接口类Q分别是IUnknown、IClassFactory、IDispatch?/strong>

  COM规范规定Mlg、Q何接口都必须从IUnknownl承QIUnknown包含三个函数Q分别是 QueryInterface、AddRef、Release。这三个函数是无比重要的Q而且它们的排列顺序也是不可改变的。QueryInterface用于查询lg实现的其它接口,说白了也是看看q个lg的父cMq有哪些接口c,AddRef用于增加引用计数QRelease用于减少引用计数。引用计C是COM中的一个非帔R要的概念。大体上单的说来可以q么理解QCOMlg是个DLLQ当客户E序要用它时p把它装到内存里。另一斚wQ一个组件也不是只给你一个h用的Q可能会有很多个E序同时都要用到它。但实际上DLL只装载了一ơ,卛_存中只有一个COMlgQ那COMlgp来释放?由客L序吗Q不可能Q因为如果你释放了组Ӟ那别人怎么用,所以只能由COMlg自己来负责。所以出C引用计数的概念,COMl持一个计敎ͼ记录当前有多h在用它,每多一ơ调用计数就加一Q少一个客L它就减一Q当最后一个客户释攑֮的时侯,COM知道已经没有人用它了Q它的用已l结束了Q那它就把它自己l释放了。引用计数是COM~程里非常容易出错的一个地方,但所qVC的各U各Lcd里已l基本上把AddRef的调用给隐含了,在我的印象里Q我~程的时侯还从来没有调用qAddRefQ我们只需在适当的时侯调用Release。至有两个时侯要记住调用ReleaseQ第一个是调用?QueryInterface以后Q第二个是调用了M得到一个接口的指针的函C后,C多查MSDN 以确定某个函数内部是否调用了AddRefQ如果是的话那调用Release的责d要归你了?IUnknown的这三个函数的实现非常规范但也非常烦琐,Ҏ出错Q所q的事我们可能永q也不需要自己来实现它们?

  IClassFactory的作用是创徏COMlg。我们已l知道COMlg实际上就是一个类Q那我们q_是怎么实例化一个类对象的?是用‘new’命o!很简单吧QCOMlg也一样如此。但是谁来new它呢Q不可能是客L序,因ؓ客户E序不可能知道组件的cd字,如果客户知道lg的类名字那组件的可重用性就要打个大大的折扣了,事实上客L序只不过知道一个代表着lg?28位的数字串而已Q这个等会再介绍。所以客h法自己创建组Ӟ而且考虑一下,如果lg是在q程的机器上Q你q能newZ个对象吗Q所以创建组件的责Q交给了一个单独的对象Q这个对象就是类厂。每个组仉必须有一个与之相关的cdQ这个类厂知道怎么样创建组Ӟ当客戯求一个组件对象的实例Ӟ实际上这个请求交l了cdQ由cd创徏lg实例Q然后把实例指针交给客户E序。这个过E在跨进E及q程创徏lg时特别有用,因ؓq时׃是一个简单的new操作可以的了,它必要l过调度Q而这些复杂的操作都交l类厂对象去做了。IClassFactory最重要的一个函数就是CreateInstanceQ顾名思议是创徏lg实例Q一般情况下我们不会直接调用它,API函数都ؓ我们装好它了,只有某些Ҏ情况下才会由我们自己来调用它Q这也是VC~写COMlg的好处,使我们有了更多的控制ZQ而VBl我们这LZ则是太少太少了?

  IDispatch叫做调度接口。它的作用何在呢Q这个世上除了C++q有很多别的语言Q比如VB?VJ、VBScript、JavaScript{等。可以这么说Q如果这世上没有q么多ؕ七八p的语言Q那׃会有IDispatch?-) 我们知道COMlg是C++c,是靠虚函数表来调用函数的Q对于VC来说毫无问题Q这本来是针对C++而设计的Q以前VB不行Q现在VB也可以用指针了,也可以通过VTable来调用函CQVJ也可以,但还是有些语a不行Q那是脚本语言Q典型的?VBScript、JavaScript。不行的原因在于它们q不支持指针Q连指针都不能用q怎么用多态性啊Q还怎么调这些虚函数啊。唉Q没办法Q也不能|这些脚本语a于不֐Q现在网上用的都是q些脚本语言Q而分布式应用也是COMlg的一个主要市场,它不得不被这些脚本语a所调用Q既然虚函数表的方式行不通,我们只能另寻他法了。时劉K英雄,IDispatch应运而生?-) 调度接口把每一个函数每一个属性都~上P客户E序要调用这些函数属性的时侯把q些~号传给IDispatch接口p了,IDispatch再根据这些编可用相应的函数Q仅此而已。当然实际的q程q比q复杂,仅给一个编号就能让别h知道怎么调用一个函数那不是天方夜潭吗,你d让别人知道你要调用的函数要带什么参敎ͼ参数cd什么以及返回什么东西吧Q而要以一U统一的方式来处理q些问题是g很头疼的事。IDispatch接口的主要函数是InvokeQ客L序都调用它,然后Invoke再调用相应的函数Q如果看一看MS的类库里实现 Invoke的代码就会惊叹它实现的复杂了Q因Z必须考虑各种参数cd的情况,所q我们不需要自己来做这件事Q而且可能永远也没q样的机会?-)

   (3) dispinterface接口、Dual接口以及Custom接口

  q一节攑֜q里g不太合适,因ؓq是在ATL~程时用到的术语。我在这里主要是惌一下自动化接口的好处及~点Q用q三个术语来解释可能会更好一些,而且以后q早会遇上它们,我将以一U通俗的方式来解释它们Q可能ƈ非那么精,好象用伪代码来描述法一栗?:)

  所谓的自动化接口就是用IDispatch实现的接口。我们已l讲解过IDispatch的作用了Q它的好处就是脚本语a象VBScript?JavaScript也能用COMlg了,从而基本上做到了与语言无关它的~点主要有两个,W一个就是速度慢效率低。这是显而易见的Q通过虚函数表一下子可以调用函CQ而通过Invoke则等于中间{了道手箋Q尤其是需要把函数参数转换成一U规范的格式才去调用函数Q耽误了很多时间。所以一般若非是q不得已我们都想用VTable的方式调用函C获得高效率。第二个~点是只能使用规定好的所谓的自动化数据类型。如果不用IDispatch我们可以想用什么数据类型就用什么类型,VC会自动给我们生成相应的调度代码。而用自动化接口就不行了,因ؓInvoke的实C码是VC事先写好的,而它不能事先预料到我们要用到的所有类型,它只能根据一些常用的数据cd来写它的处理代码Q而且它也要考虑不同语言之间的数据类型{换问题。所以VC自动化接口生成的调度代码只适用于它所规定好的那些数据cdQ当然这些数据类型已l够丰富了Q但不能满自定义数据结构的要求。你也可以自己写调度代码来处理你的自定义数据l构Q但qƈ不是一件容易的事。考虑到IDispatch的种U缺?它还有一个缺点,是使用ȝQ?-) )现在一般都推荐写双接口lgQ称为dual接口Q实际上是从IDispatchl承的接口。我们知道Q何接口都必须?IUnknownl承QIDispatch接口也不例外。那从IDispatchl承的接口实际上q于有两个基类Q一个是IUnknownQ一个是IDispatchQ所以它可以以两U方式来调用lgQ可以通过 IUnknown用虚函数表的方式调用接口ҎQ也可以通过IDispatch::Invoke自动化调度来调用。这有了很大的灉|性,q个lg既可以用于C++的环境也可以用于脚本语言中,同时满了各斚w的需要?

  相对比的Qdispinterface是一U纯_的自动化接口,可以单的把它看作是IDispatch接口 (虽然它实际上不是?Q这U接口就只能通过自动化的方式来调用,COMlg的事件一般都用的是这UŞ式的接口?

  Custom接口是从IUnknown接口z的类Q显然它只能用虚函数表的方式来调用接口?

   (4) COMlg有三U,q程内、本地、远E。对于后两者情况必调度接口指针及函数参数?/strong>

  COM是一个DLLQ它有三U运行模式。它可以是进E内的,卛_调用者在同一个进E内Q也可以和调用者在同一个机器上但在不同的进E内Q还可以Ҏ和调用者在两台机器上。这里有一个根本点需要牢讎ͼ是COMlg它只是一个DLLQ它自己是运行不h的,必须有一个进E象父亲般照֮才行Q即COMlg必须在一个进E内.那谁充当看护人的责Q呢?先说说调度的问题。调度是个复杂的问题Q以我的知识q讲不清楚这个问题,我只是一般性的谈谈几个最基本的概c我们知道对于WIN32E序Q每个进E都拥有4GB的虚拟地址I间Q每个进E都有其各自的编址Q同一个数据块在不同的q程里的~址很可能就是不一LQ所以存在着q程间的地址转换问题。这是调度问题。对于本地和q程q程来说QDLL 和客L序在不同的编址I间Q所以要传递接口指针到客户E序必须要经q调度。Windows 已经提供了现成的调度函数Q就不需要我们自己来做这个复杂的事情了。对q程lg来说函数的参C递是另外一U调度。DCOM是以RPC为基的,要在|络间传递数据必遵守标准的|上数据传输协议Q数据传递前要先打包Q传递到目的地后要解包,q个q程是调度Q这个过E很复杂Q不qWindows已经把一切都l我们做好了Q一般情况下我们不需要自己来~写调度DLL?

  我们刚说q一个COMlg必须在一个进E内。对于本地模式的lg一般是以EXE的Ş式出玎ͼ所以它本n已l是一个进E。对于远EDLLQ我们必L一个进E,q个q程必须包含了调度代码以实现基本的调度。这个进E就是dllhost.exe。这是COM默认的DLL代理。实际上在分布式应用中,我们应该用MTS来作为DLL代理Q因为MTS有着很强大的功能Q是专门的用于管理分布式DLLlg的工兗?

  调度L们很q又g很远Q我们编E时很少x到它Q这也是COM的一个优点之一Q既q_无关性,无论你是q程的、本地的q是q程内的Q编E是一LQ一切细节都由COM自己处理好了Q所以我们也不用qq个问题Q只要有个概念就可以了,当然如果你对调度有自qD的要求需要深入了解调度的整个q程了,q里推荐一本《COM+技术内q》,q绝Ҏ一本讲调度的好书?

   (5) COMlg的核心是IDL?/strong>

  我们希望软g是一块块D出来的,但不可能是没有规定的胡ؕ拼接QL要遵守一定的标准Q各个模块之间如何才能亲密无间的合作Q必要事先共同制订好它们之间交互的规范Q这个规范就是接口。我们知道接口实际上都是U虚c,它里面定义好了很多的U虚函数Q等着某个lgd现它Q这个接口就是两个完全不相关的模块能够组合在一L关键试想一下如果我们是一个应用Y件厂商,我们的Y件中需要用到某个模块,我们没有旉自己开发,所以我们想到市Z找一扄有没有这L模块Q我们怎么L呢?也许我们需要的q个模块在业界已l有了标准,已经有h制订好了标准的接口,有很多组件工具厂商已l在自己的组件中实现了这个接口,那我们寻扄目标是q些已经实现了接口的lgQ我们不兛_lg从哪来,它有什么其它的功能Q我们只兛_它是否很好的实现了我们制订好的接口。这U接口可能是业界的标准,也可能只是你和几个厂商之间内部制订的协议Q但M它是一个标准,是你的Y件和别h的模块能够组合在一L基础Q是COMlg通信的标准?

  COMh语言无关性,它可以用M语言~写Q也可以在Q何语aq_上被调用。但至今为止我们一直是以C++的环境中谈COMQ那它的语言无关性是怎么体现出来的呢Q或者换句话_我们怎样才能以语a无关的方式来定义接口呢?前面我们是直接用U虚cȝ方式定义的,但显然是不行的,除了C++谁还认它呢?正是Zq种考虑Q微软决定采用IDL来定义接口。说白了QIDL实际上就是一U大安认识的语aQ用它来定义接口Q不论放到哪个语aq_上都认识它。我们可以想象一下理想的标准的组件模式,我们L从IDL开始,先用IDL制订好各个接口,然后把实现接口的d分配不同的hQ有的h可能善长用VCQ有的h可能善长用VBQ这没关p,作ؓ目负责人我不关心这些,我只兛_你把最l的DLL 拿给我。这是一U多么好的开发模式,可以用Q何语a来开发,也可以用M语言来欣赏你的开发成果?br>
      让我们看IUnknow接口的定义文件是怎样的?br>

[
  local,
  
object,
  uuid(
00000000-0000-0000-C000-000000000046),
  pointer_default(unique)
]

interface IUnknown
{
    typedef [unique] IUnknown 
*LPUNKNOWN;

cpp_quote(
"//////////////////////////////////////////////////////////////////")
cpp_quote(
"// IID_IUnknown and all other system IIDs are provided in UUID.LIB")
cpp_quote(
"// Link that library in with your proxies, clients and servers")
cpp_quote(
"//////////////////////////////////////////////////////////////////")

    HRESULT QueryInterface(
        [
in] REFIID riid,
        [
out, iid_is(riid)] void **ppvObject);
    ULONG AddRef();
    ULONG Release();
}

[local]属性禁止生网l代码?br>[
object]属性是表明定义的是一个COM接口Q而不是DEC风格的接口?br>[uuid]属性给接口一个GUID?br>[unique]属性表明null(I?指针Z个合法的参数倹{?br>[pointer_defaul]属性所有的内嵌指针指定一个默认指针属?br>typedef [unique] IUnknown *LPUNKNOWN;q是一个类型定?br>cpp_quoteq个比较有趣Q这是一个在idl文g写注解的Ҏ。这些注解将保存?/span>***.h?/span>***_i.c文g?br>[in]表示q个参数是入?br>[out]表示q个参数是出?br>[iid_is(riid)]表示q个参数需要前一个的riid 参数?/span>

 

   (6) COMlg的运行机Ӟ即COM是怎么跑v来的?/strong>

  q部分我们将构造一个创建COMlg的最框架结构,然后看一看其内部处理程是怎样?

    IUnknown *pUnk=NULL;
    IObject 
*pObject=NULL;
    CoInitialize(NULL);
    CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown, (
void**)&pUnk);
    pUnk
->QueryInterface(IID_IOjbect, (void**)&pObject);
    pUnk
->Release();
    pObject
->Func();
    pObject
->Release();
    CoUninitialize(); 


  q就是一个典型的创徏COMlg的框Ӟ不过我的兴趣在CoCreateInstancew上Q让我们来看看它内部做了一些什么事情。以下是它内部实现的一个伪代码:

    CoCreateInstance(.)
    
{
    .
    IClassFactory 
*pClassFactory=NULL;
    CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (
void **)&pClassFactory);
    pClassFactory
->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
    pClassFactory
->Release();
    ..
   }
 

 

  q段话的意思就是先得到cd对象Q再通过cd创徏lg从而得到IUnknown指针。l深入一步,看看CoGetClassObject的内部伪码:

   CoGetClassObject(..)
   
{
    
//通过查注册表CLSID_ObjectQ得知组件DLL的位|、文件名
    
//装入DLL?br>    //使用函数GetProcAddress()得到DLL库中函数DllGetClassObject的函数指针?br>    //调用DllGetClassObject 
   }

    DllGetClassObject是干什么的Q它是用来获得类厂对象的。只有先得到cd才能d建组?
    下面是DllGetClassObject的伪码:
    DllGetClassObject()
    
{
    
    CFactory
* pFactory= new CFactory; //cd对象
    pFactory->QueryInterface(IID_IClassFactory, (void**)&pClassFactory);
    
//查询IClassFactory指针
    pFactory->Release();
    
    }

    CoGetClassObject的流E已l到此ؓ止,现在q回CoCreateInstanceQ看看CreateInstance的伪码:
    CFactory::CreateInstance(..)
    
{
    ..
    CObject 
*pObject = new CObject; //lg对象
    pObject->QueryInterface(IID_IUnknown, (void**)&pUnk);
    pObject
->Release();
    ..
    }
 

 

  下图是从VCKBASE中COPY来的一个例E图Q从图中可以清楚的看到COM的整个流E?

 

   (7) 一个典型的自注册的COM DLL所必有的四个函?

  DllGetClassObject:用于获得cd指针

  DllRegisterServer:注册一些必要的信息到注册表?

  DllUnregisterServer:卸蝲注册信息

  DllCanUnloadNow:pȝI闲时会调用q个函数Q以定是否可以卸蝲DLL

  DLLq有一个函数是DllMain,q个函数在COM中ƈ不要求一定要实现它,但是在VC生成的组件中自动都包含了它,它的作用主要是得C个全局的实例对象?

   (8) 注册表在COM中的重要作用

  首先要知道GUID的概念,COM中所有的cR接口、类型库都用GUID来唯一标识QGUID是一?28位的字串Q根据特制算法生成的GUID可以保证是全世界唯一的?COMlg的创建,查询接口都是通过注册表进行的。有了注册表Q应用程序就不需要知道组件的DLL文g名、位|,只需要根据CLSID查就可以了。当版本升的时侯,只要改一下注册表信息可以神不知g觉的转到新版本的DLL?

   (9) 如何注册和卸载COMlg

     可能大家也发CQ在调用整个COMlg的过E中Qƈ没有代码来明的执行加蝲DLL的操作,那么到底COM是怎样被调用到得呢Q实际上Q在COMlg使用前,我们必须要先把它q行注册?br>     打开命o行窗口,到DLL的目录下Q运行regsvr32 xxx.dllQxxx.dll是你的包含COMlg的DLL文gQ,q行q个命oӞDLL文g中的DllRegisterServer׃被系l调用,q个COMlg的信息就注入到注册表中去了,q时E序可以通过GUID从注册表中找C的COMlg了。相反,如果你想卸蝲你的COMlgQ只需要运行regsvr32 /u xxx.dllQ多了个/uQ,DLL文g中的DllUnregisterServer是被系l调用,q个COMlg的信息就被从注册表中去除了,也就完成了卸载?br>
   (10)Z么要用COM

  软g工程发展C天,从一开始的l构化编E,到面向对象编E,再到现在的COM~程Q目标只有一个,是希望软g能象U方块一h累v来的Q是l装h的,而不是一点点~出来的。结构化~程是函数块的Ş式,通过把一个Y件划分成许多模块Q每个模块完成各自不同的功能Q尽量做到高内聚低藕合,q已l是一个很好的开始,我们可以把不同的模块分给不同的hdQ然后合C块,q已l有了组装的概念了。Y件工E的核心是要模块化Q最理想的情况就?00%内聚0%藕合。整个Y件的发展也都是朝着q个方向走的。结构化~程方式只是一个开始。下一步就出现了面向对象编E,它相对于面向功能的结构化方式是一个巨大的q步。我们知道整个自然界都是由各U各样不同的事物l成的,事物之间存在着复杂的千丝万~的关系Q而正是靠着事物之间的联pR交互作用,我们的世界才是有生命力的才是zd的。我们可以认为在自然界中事物做ؓ一个概念,它是E_的不变的Q而事物之间的联系是多变的、运动的。事物应该是q个世界的本质所在。面向对象的着眼点是事物Q就是这U稳定的概念。每个事物都有其固有的属性,都有其固有的行ؓQ这些都是事物本w所固有的东西,而面向对象的Ҏ是描述U稳定的东西。而面向功能的模块化方法它的着眼点是事物之间的联系Q它g看不C物的概念它只注重功能Q我们^常在划分模块的时侯有没有惌q个函数与哪些对象有兛_Q很有么想Q一个函数它实现一U功能,q个功能必定与某些事物想联系Q我们没有去掌握事物本n而只考虑事物之间是怎么怺作用而完成一个功能的。说白了Q这叫本末倒置Q也叫急功q利Q因Z是我们智慧不够,只是因ؓ我们没有多想一步。面向功能的l构化方法因为它注意的只是事物之间的联系Q而联pL多变的,事物本n可能不会发生大的变化Q而联pd是很有可能发生改变的Q联pM变,那就是另一个世界了Q那是另一U功能了。如果我们用面向对象的方法,我们可以以不变应万变,只要事先把事物用cLq好Q我们要改变的只是把q些c联pv来的ҎQ只是重C用我们的cdQ而面向过E的Ҏ因ؓ它构造的是一个不E_的世界,所以一点小的变化也可能导致整个系l都要改变。然而面向对象方法仍然有问题Q问题在于重用的Ҏ。搭U木式的软g构造方法的基础是有许许多多各种各样的可重用的部件、模块。我们首先想到的是类库,因ؓ我们用面向对象的Ҏ产生的直接结果就是许多的cR但cd的重用是Z源码的方式,q是它的重大~陷。首先它限制了编E语aQ你的类库L用一U语a写的吧,那你׃能拿到别的语a里用了。其ơ你每次都必重新编译,只有~译了才能与你自q代码l合在一L成可执行文g。在开发时q倒没什么,关键在于开发完成后Q你的EXE都已l生成好了,如果q时侯你的类库提供厂商告诉你他们又做好了一个新的类库,功能更强大速度更快Q而你Z心动又想把这新版的类库用C自己的程序中Q那你就必须重新~译、重新调试!q离我们理想的积木式软g构造方法还有一定差距,在我们的设想里希望把一个模块拿出来再换一个新的模块是非常方便的事Q可是现在不但要重新~译Q还要冒着很大的风险,因ؓ你可能要重新改变你自q代码。另一U重用方式很自然地就惛_了是DLL的方式。Windows里到处是DLLQ它是Windows 的基Q但DLL也有它自q~点。ȝ一下它臛_有四点不?1)函数重名问题。DLL里是一个一个的函数Q我们通过函数名来调用函数Q那如果两个DLL里有重名的函数怎么办?(2)各编译器对CQ+函数的名UCC兼容问题。对于CQ+函数Q编译器要根据函数的参数信息为它生成修饰名,DLL库里存的是q个修饰名,但是不同的编译器产生修饰的方法不一P所以你在VC 里编写的DLL在BC里就可以用不了。不q也可以用extern "C";来强调用标准的C函数Ҏ,关闭修饰功能Q但q样也׃CQ+的重载多态性功能?3)路径问题。放在自q目录下面Q别人的E序找不到Q放在系l目录下Q就可能有重名的问题。而真正的lg应该可以攑֜M地方甚至可以不在本机Q用h本不需考虑q个问题?4)DLL与EXE的依赖问题。我们一般都是用隐式q接的方式,是~程的时侯指明用什么DLLQ这U方式很单,它在~译时就把EXE与DLLl在一起了。如果DLL发行了一个新版本Q我们很有必要重新链接一ơ,因ؓDLL里面函数的地址可能已经发生了改变。DLL的缺点就是COM的优炏V首先我们要先把握住一点,COM和DLL一样都是基于二q制的代码重用,所以它不存在类库重用时的问题。另一个关键点是,COM本n也是DLLQ既使是ActiveX控g.ocx它实际上也是DLLQ所以说DLL在还是有重用上有很大的优势,只不q我们通过制订复杂的COM协议Q通COM本n的机制改变了重用的方法,以一U新的方法来利用DLLQ来克服DLL本n所固有的缺P从而实现更高一U的重用Ҏ。COM没有重名问题Q因为根本不是通过函数名来调用函数Q而是通过虚函数表Q自然也不会有函数名修饰的问题。\径问题也不复存在Q因为是通过查注册表来找lg的,攑֜什么地斚w可以Q即使在别的机器上也可以。也不用考虑和EXE的依赖关pMQ它们二者之间是松散的结合在一P可以L的换上组件的一个新版本Q而应用程序؜然不觉?br>



Saga 2009-07-17 16:41 发表评论
]]>
þþþþùƷ| þ99Ʒþþþþ| պһƵþ| þѾƷƵ| Ʒþþþþ| þݺҹҹ2014| ŷƷþþ| 99þó18վ| þҹҹݺ| þþþƷ޳18վ| ŷ龫Ʒþþþþ| 99ƷþþƷһ| 99þùۺϾƷ| 91þþƷӰ| þþþþAVר| ŷþۺ㽶| þۺŷ| þþþһƷɫ| Ʒþþþþ| þ㽶߿ۿ | 99þ99þþƷѿ | Ʒþþþþ³| þ99Ʒһ| þþƷˬӰ| ƷŷƬþùŷ | þֻǾƷ23| þþƷƷ| 㽶þһ޶ӰԺ | þþþþùaѹۿ| þþƷAV㽶| ҹƷþþþþ99| 鶹Ʒþþþþþ99| ˺ݺۺ88ۺϾþ| ŷƷרþ| þþƷĻ23ҳ| Ƶþ| ҹƷþþþþ| þþоƷ| ޹Ʒһþhs| 99ξþþŷƷվ| þˬһ|