描述:
请问COM和DLL到底有什么区别,我知道是COM是DLL的一种,而且VC写的DLL动太库,DELPHI也可以调用,而且DELPHI写的界面程序可以不改,只改DLL,一样也可以用,这COM除了加了GUID,搁在REGEDIT表里么?谁能和我讲清楚呀!?????????????
解决方案1:
将COM同DLL相比或相提并论也是不合适的,实际上COM是使用了DLL来给组件提供动态链接的能力。在我看来,利用DLL的动态链接能力最佳的方法是COM,
解决方案2: COM和DLL(指动态连接库技术)都是为了实现代码的重用,代码都是以函数的形式存放的,而代码的使用是以调用函数的形式使用,只不过COM以接口的成员函数的形式存放代码,而DLL以导出函数的形式存放代码而已。要实现代码的重用,就要暴露(也就是让客户端知道)函数地址。
不管任何原型的函数,对CPU来说只不过是个4字节地址,函数调用只不过是代码跳到指定的函数地址继续执行而已,而所谓的不同的函数参数的类型,返回值的类型都只不过是代码跳转前所做的准备工作和代码跳回后所做的扫尾工作不同而已,因此要暴露代码以供重用,就是用一种方法让客户程序知道函数地址,而准备和扫尾工作一般是由编译器通过函数声明(也就是头文件)来自动生成。
DLL中,导出的函数地址存放在一个节(section,PE文件(.obj、.sys、.exe、.dll等)格式的一部分,可用SDK的Image Help函数对一个PE格式的文件操作section)中,其实就是一个4字节的数组,编译器根据头文件的函数声明在DLL文件的另一个节中找到对应函数的地址在导出节中的序号,然后编译器将把调用代码变成
call LIST[ index ] ;call代表代码跳转,LIST就是那个地址数组,而index对应函数的序号
编译时刻就已经知道了LIST和index,但不能变成
call 0xXXXXXXXX ;因为有可能发生重定位问题
因此,DLL是在编译时刻就已经决定好了函数地址,不过由于通过数组间接引用,所以可以实现所谓的挂接API技术。
COM中,接口指针(如IUnknown*)是一个指向函数地址数组的指针,就如同指向上面的LIST的指针。而这个指针不象DLL一样由编译器生成(不准确,因为有重定位问题),而是由编写COM组件的程序员生成,即程序员必须负责填写接口指针指向的函数地址数组中的各个元素。在C++编译器下这可以通过类的构造实现,这也是类厂存在的一个重要原因。在COM下对接口IUnknown::AddRef的调用就会被编译成
call (*m_pUnk)[ Index_AddRef ] ;Index_AddRef是AddRef在这个数组中的位置
因此COM和DLL在暴露函数方式上的重要区别就是那个函数地址数组是否静态生成。COM是通过类厂动态生成,而DLL是通过编译器静态生成(实际是加载器动态生成)。而至于COM提供的各种服务(如同步等),楼主只有自己找书慢看了。
COM只是一个数学模型,微软的COM运行时期库是它的一个实现。
楼主所谓的COM应该指COM组件,其实现形式只有dll和exe两种(Windows下),目的和DLL一样,暴露dll或exe中封装的功能代码。而功能代码的执行都是以调用函数的形式,因此所谓的暴露方法,也就是给出那个函数的函数地址。
在DLL中,函数地址是通过导出节(export section)来暴露的,而在COM组件中,函数地址是通过接口指针来暴露的。接口指针指向的是一个函数地址数组,而相应的导出函数就是通过这个数组的元素暴露的。如IUnknown::AddRef的地址一般就是那个数组的第一个元素。
因此他们的暴露方式不同,而COM技术还提供了很多功能,如同步(套间技术)、异步调用、DCOM等,而DLL只不过是一个代码封装形式而已(如同exe、sys等),它们完全不是同一个概念
up