




已阅读5页,还剩12页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
北京邮电大学软件学院_09-10_学年第_2_学期实验报告 课程名称: COM原理及应用 项目名称: 分布式计算实验 项目完成人:姓名:_ 都晨辉_学号:_09Z0589_指导教师:_卢本捷_日 期: 2010 年 4 月 8 日第一个实验:仿真组件对象一 实验目的1. 学习掌握开发编译器中性、可维护、可升级的组件对象的基本原理、基本方法;2. 学习分别使用异种编译器开发组件的服务器端和客户端。二 实验内容使用VC开发一个以DLL作为载体的仿真COM对象, 此对象支持多个接口.每个接口支持不同的功能. 使用BC开发一个客户,创建此仿真COM对象,并调用它的不同接口的功能. 要求在试验过程中主要完成如下工作:1. 验证名字改编造成的编译器依赖性.2. 验证头文件的改变带来的DLL升级的问题.3. 验证接口类带来的升级便利.4. 验证普通析构函数带来的编译器依赖性.5. 验证普通析构函数带来的内存泄漏.6. 验证虚拟析构函数带来的编译器依赖性.7. 验证RTTI的编译器依赖性.8. 验证引用计数带来的客户端的便利.三 实验环境1 Windows 2000,或Windows 2003 或 Windows XP2 VC 6.0 或者VS.net 2002 或2003 或20053 CBuilder 6.0 或者 BC 4.0 或5.0或其他。(注:组件对象和调用该对象的客户端的开发可以不必选用vc,bc,也可以选择其他编译器,但必须使用不同的环境)四 实验要求1 自行拟定组件的业务功能,但应与讲义中例程不同。2 逐步完善其结构,记录下在此过程中客户端的症状。(比如以屏幕截屏的方式)3 分析原因, 提出解决方法4 记录试验过程,以及主要源代码5 撰写实验报告.五 实验步骤1 使用VC建立一个DLL,输出一个类。在VC客户端使用此类。2 验证bc的客户端无法使用此类3 以避免名字改编的方式输出一个函数以代替构造函数。4 验证功能函数被名字改编导致无法链接5 将功能函数改为虚函数并验证虚函数可以顺利调用6 验证虚析构函数的编译器依赖性7 以虚功能函数的方式来完成对象的释放工作8 验证数据成员的存在导致升级困难。9 验证参数入栈方向不一致所导致的错误10 从实现类中分离出接口类。客户端只与接口类交互。11 接口类使用普通析构函数。验证同种编译器产生的客户端会出现内存泄漏,验证异种编译器所产生的客户端无法链接。12 接口类使用虚析构函数,验证同种编译器产生的客户端内存泄漏消失,验证异种编译器所产生的客户端仍然无法链接。13 接口类进行改造,以纯虚函数的方式提供释放对象的功能。14 验证接口类不变时,实现类可以进行任意的更新,而客户端可以无缝升级。15 验证接口类的变化带来升级的困难。16 使用多接口的方式对对象进行扩展,验证在同种编译器的客户端可以顺利升级。17 验证以上情形在异种客户端无法链接。18 以功能函数的方式编译器中性地实现接口转换,验证异种编译器方式下也可顺利升级。19 验证一个对象的多个接口之间的紧密耦合性。20 以引用计数的方式消除多接口的紧密耦合性。实验过程:1. 使用vc建立一个dll,输出类。 头文件:class _declspec(dllexport) CCalculateint num1;int num2;public:CCalculate(int a,int b);CCalculate(void);int _stdcall add();int _stdcall sub();2. 在解决方案下添加一个客户端 ,使用vc客户端调用此类l 建立vc 控制台程序 VCClient此时编译,编译器会提示:No such file or directory的错误,这需要设置包含路径,包含DLL头文件的目录。l 设定包含路径:$(SolutionDir)FastString再次编译,依然会提示链接错误。这需要设置链接路径以及链接库。至此编译成功,运行通过。l 设定链接路径:$(SolutionDir)Debugl 设定链接库:FastString.lib至此编译成功,运行通过。3. 使用BC创建一个客户端 BCClientl 设定包含路径:Project Options Directories l View Project Manager 添加 Calculate.lib文件 提示:无效的OMF, Possible COFF.这是需要利用coff2omf工具将lib文件进行转换。l 使用coff2omf 工具 coff2omf.exe FastString.lib FastStringBC.lib 进行转换。l 把FastStringBC.lib 包含到项目中l 提示构造函数无法链接。 4. 在VC中,Calculate 输出函数:externC_declspec(dllexport) ICalculate* CreateObject(int a, int b);BCClient:CCalculate *pC = CreateObject(5,2); / 通过!但是调用其他函数时仍会提示链接错误。int a = pC-add(); / 提示链接出错。5. 把add 和 sub 改为虚函数。以上链接通过。delete pC; / 链接出错。6. 把析构函数改为虚函数以上链接仍然出错。这是由于名字改编造成的。7. 添加Delete函数:void CCalculate:Delete () delete this;pC-Delete() ; / 链接通过。8. BC的运行过程。 直接运行提示出错:找不到DLLProject options-directories 将 Final output 设定为 Dll 所在位置。9. add 或者 sub 的执行情况:这时能够输出结果10. 将其改为_stdcall 执行结果正常11. 取消对CFastString的输出。正常。12. 对数据的敏感性: 客户编译器与服务器编译器同时依赖于同一个c+类定义, 在类的定义部分:加上: Public: int a; int b; 构造函数中: a=2; b=5; 以此文件生成dll,以此文件生成客户。得到版本1.改变a,b的定义顺序。生成dll,和客户。得到版本2.当打乱客户端与DLL搭配顺序后,会发现输出结果也错乱了。正确结果应该为:打乱后的输出结果为:13. 对函数的敏感性:定义两个虚函数:virtual int fa(); virtual int fb(); 分别实现之。 编译服务器端和客户端。得到版本1. 改变定义顺序: virtual int fb(); virtual int fa();编译服务器端和客户端。得到版本2.当打乱客户端与DLL搭配顺序后,会发现输出结果也错乱了。正常结果为:打乱后的结果为:14. 对普通函数的不敏感性:这里客户要用同种编译器,即vc对于以上的虚函数,改为非虚的。打乱次序后,调用不会出错。说明是通过名字解析的方式进行的。15. 所以要对接口进行抽象。降低耦合性。添加接口类: #pragma once#include IExtensibleObject.hclass _declspec(dllexport) ICalculate:public IExtensibleObjectpublic: virtual int _stdcall add(void)=0; virtual int _stdcall sub( void)=0; ICalculate(void); ICalculate(void); 验证:l Vc客户端:a) 普通析构函数,内存泄漏。b) 虚析构函数,无内存泄漏。l Bc客户端:在BC的客户端,无论调用普通的析构函数还是虚析构函数,都会提示链接错误:16. 所以接口改为如下形式:l 取消输出l 增加Delete 虚函数。l 采用默认的构造和析构函数。 BC 客户端改为: ICalculate *pIC = CreateObject(5,2); int a = pIC-add(); ShowMessage(a) ; pIC-Delete();称为新的版本117. 对接口进行改变 #pragma once#include IExtensibleObject.hclass ICalculate:public IExtensibleObjectpublic: virtual void _stdcall Delete()=0; virtual int _stdcall add(void)=0; virtual int _stdcall sub( void)=0; virtual int _stdcall mul(void)=0;FastString 实现新函数。客户端对其进行调用。生成版本2.打乱版本1和2搭配次序。l 老客户用新对象,正常。l 新客户用老对象,失败。18. 增加新的接口: class IPOpublic:virtual void _stdcall Delete()=0;virtual void _stdcall Swap()=0;virtual int _stdcall Geta()=0;多重继承:class CCalculate:public ICalculate,public IPO 客户端: IPO *pIPO = dynamic_cast(pIC);验证l VC在版本之间可以正常运行。l BC 客户端运行异常19. 中性的类型转换接口改为如下形式:增加dynami 函数。class IExtensibleObjectpublic: virtual void _stdcall Dynamic(char* name,void* ppI)=0;class ICalculate:public IExtensibleObjectpublic: virtual void _stdcall Delete()=0; virtual int _stdcall add(void)=0; virtual int _stdcall sub( void)=0; virtual int _stdcall mul(void)=0;class IPO:public IExtensibleObjectpublic:virtual void _stdcall Delete()=0;virtual void _stdcall Swap()=0;virtual int _stdcall Geta()=0;class CCalculate:public ICalculate,public IPO实现方式:void CCalculate:Dynamic(char *name,void*ppI) if(strcmp(name,ICalculate)=0)*ppI=static_cast(this);else if(strcmp(name,IPO)=0)*ppI=static_cast(this);else if(strcmp(name,IExtensibleObject)=0)*ppI=static_cast(this);调用方式: IPO *pIPO; pIC-Dynamic (IPO,(void*)&pIPO);20. 引用计数。在IExtensibleObject接口中增加virtual void _stdcall DuplicataPointer(void)=0;virtual void _stdcall DestroyPointer(void)=0;两个函数实现方式:void _stdcall DuplicataPointer(void)+m_cPtrs;void _stdcall DestroyPointer(void)if(-m_cPtrs=0)delete this;客户端修改为:int _tmain(int argc, _TCHAR* argv)ICalculate *pIC = CreateObject(5,2); IPO *pIPO; IExtensibleObject * pIEO;pIC-Dynamic (IPO,(void*)&pIPO);pIPO-Swap();int m = pIPO-Geta();printf(The num1 is %d n,m);system(pause);pIPO-DestroyPointer();pIC-DestroyPointer();return 0;第二个实验: 使用 ATL,MFC类库来开发组件对象。一 实验目的:1. 学习使用ATL,MFC类库来进行组件对象的开发。2. 学习调用组件的客户端程序开发二 实验内容:使用ATL开发一个自动化对象。此自动化对象包含2个双接口,分别实现多个功能。使用MFC开发一个组件对象,此对象支持2个功能接口,分别实现多种功能。开发一个客户端分别调用以上两个对象的各个接口。三 实验环境1. Windows 2000,或Windows 2003 或 Windows XP2. VC 6.0 或者VS.net 2002 或2003 或20053. ATL,MFC库。四 实验要求1. 自行拟定组件的业务功能。2. 客户端可以用多种方法来进行调用。(迟绑定,早绑定等)3. 记录试验过程,以及
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论