分布式实验报告张莹127129Word文档下载推荐.docx

上传人:b****7 文档编号:22411899 上传时间:2023-02-04 格式:DOCX 页数:40 大小:2.83MB
下载 相关 举报
分布式实验报告张莹127129Word文档下载推荐.docx_第1页
第1页 / 共40页
分布式实验报告张莹127129Word文档下载推荐.docx_第2页
第2页 / 共40页
分布式实验报告张莹127129Word文档下载推荐.docx_第3页
第3页 / 共40页
分布式实验报告张莹127129Word文档下载推荐.docx_第4页
第4页 / 共40页
分布式实验报告张莹127129Word文档下载推荐.docx_第5页
第5页 / 共40页
点击查看更多>>
下载资源
资源描述

分布式实验报告张莹127129Word文档下载推荐.docx

《分布式实验报告张莹127129Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《分布式实验报告张莹127129Word文档下载推荐.docx(40页珍藏版)》请在冰豆网上搜索。

分布式实验报告张莹127129Word文档下载推荐.docx

13.接口类进行改造,以纯虚函数的方式提供释放对象的功能。

14.验证接口类不变时,实现类可以进行任意的更新,而客户端可以无缝升级。

15.验证接口类的变化带来升级的困难。

16.使用多接口的方式对对象进行扩展,验证在同种编译器的客户端可以顺利升级。

17.验证以上情形在异种客户端无法链接。

18.以功能函数的方式编译器中性地实现接口转换,验证异种编译器方式下也可顺利升级。

19.验证一个对象的多个接口之间的紧密耦合性。

20.以引用计数的方式消除多接口的紧密耦合性。

软件下载

虚拟光驱

C++builder

vs2012

实验过程

1、打开visualstudio,选择visualC++开发设置。

然后点击“启动”。

使用vc建立一个dllFastStringDll

●Win32,名称为FastStringDll

●Win32控制台应用程序

●DLL

●导出符号。

运行一下,可以成功。

添加类FastString

●右键点击项目

●添加

●类

●C++类

●输入类名FastString

●完成

输入代码

代码如下

产生头文件:

FastString.h

class__declspec(dllexport)FastString

{char*m_psz;

public:

FastString(char*psz);

~FastString(void);

intLength(void);

intFind(char*psz);

};

新增实现文件:

FastString.cpp

#include"

stdafx.h"

//预编译

FastString.h"

#include<

string.h>

FastString:

:

FastString(char*psz)

m_psz(newchar[strlen(psz)+1])

{strcpy_s(m_psz,strlen(psz)+1,psz);

}//分配内存

~FastString(void)

{delete[]m_psz;

}//释放内存

intFastString:

Length(void){

returnstrlen(m_psz);

}//计算长度

Find(char*psz)

{return0;

}//省略,这不是我们讨论的重点.

选择release,再运行一下。

这时就生成了dll文件

2、在解决方案下添加一个客户端,使用vc客户端调用此类

●建立vc控制台程序VCClient

●设定项目属性-》配置属性:

●C/C++-》常规:

附加包含目录:

编辑:

新行:

$(SolutionDir)\FastStringDll这里路径要引对,要引入dll文件。

D:

\com\FastStringDll\Release

\com\FastStringDll\FastStringDll

●链接器-》常规:

附加库目录:

$(SolutionDir)$(Configuration)\

●链接器-》输入:

附加依赖项:

编辑加入:

FastStringDll.lib

●代码VCClient.cpp

#include<

iostream>

usingnamespacestd;

int_tmain(intargc,_TCHAR*argv[])

{

FastString*pFS=newFastString("

fdfd"

);

intres=pFS->

Length();

cout<

<

res<

endl;

return0;

}

●设定VCClient为启动项目

运行成功。

3.使用BC创建一个客户端BCClient

●打开bc创建一个VCLFormsApplication应用程序。

●在VC的解决方案文件夹下新建文件夹筛选器BCClient。

●在BCClient内对BC项目全部保存起来,再导入到VCClient里面

●在BC窗口界面点一下button,再点一下视图,就能添加一个按钮了。

这里产生点击click处理事件。

●在Unit1.cpp中,#include"

Unit1.h"

后面加入#include"

●运行,发现[bcc32Error]Unit1.cpp(7):

E2209Unabletoopenincludefile'

FastString.h'

●设定包含路径:

Project-》Options–》C++Compiler–》Directories&

conditional

includefilesearchpath加上../FastStringDll

VS2012是在属性-》配置属性-》VC++目录-》包含目录

●编译通过

●加入代码:

FastString*pFS=newFastString("

●对于以上代码提示无法链接

[ilink32Error]Error:

Unresolvedexternal'

FastString(char*)'

referencedfromD:

\TEST\FASTSTRINGDLL\BCCLIENT\WIN32\DEBUG\UNIT1.OBJ

●View–》ProjectManager添加FastString.lib文件

链接失败提示:

无效的OMF,PossibleCOFF.

'

\TEST\FASTSTRINGDLL\DEBUG\FASTSTRINGDLL.LIB'

containsinvalidOMFrecord,type0x21(possiblyCOFF)

这里是因为跨平台,所以vc下引用dll和bc下引用效果不一样。

所以如何解决这个问题呢?

●使用coff2omf工具,cmd中输入“coff2omf.exeFastStringDll.libbc.lib”进行转换。

需要先退出C盘,进入D盘lib文件所在的地方

到上一级目录,请使用cd..

进入D盘,请使用d:

进入想要的目录,请使用cd

这里还有其他两种方法

一、使用implib命令

1、用C++Builder的implib工具生成DLL对应的lib文件。

生成lib文件之后,C++Builder便可以使用这个lib文件了。

2、在.h中用extern"

C"

修饰VC导出的DLL函数。

如:

extern"

__declspec(dllexport)intaFunc(inta),就可以调用了。

二、coff2omf.exe

工具程序coff2omf.exe将.lib转换为BCB可用的,然后添加进工程,直接使用VC的头文件就可以了。

三、动态调用

C/C++code

//Main.h

HINSTANCEhDllInst;

//声明Dll句柄

int(__stdcall*sdfm)(unsignedchar,unsignedshort,long);

//声明变量

//Main.cpp

void__fastcallTForm:

FormCreate(TObject*Sender)

{//框架启动时初始化Dll模块,这里以DllName.dll为例

if(NULL==hDllInst)

hDllInst=LoadLibrary("

DllName.dll"

if(hDllInst)

sdfm=(int(__stdcall*)(unsignedchar,unsignedshort,long))GetProcAddress(hDllInst,"

sdfm"

}

生成的新lib文件如图:

●把bc.lib包含到项目中

●提示构造函数无法链接。

4.在VC中,FastString输出函数CreateObject:

FastString.h文件:

extern"

__declspec(dllexport)FastString*CreateObject(char*psz);

FastString.cpp文件:

FastString*CreateObject(char*psz)

{

returnnewFastString(psz);

}

●重新编译,重新更新lib文件。

●BCClient:

代码改为:

FastString*pFS=CreateObject("

fdfdd"

●编译通过!

●但是如果加上:

pFS->

Length();

//提示链接出错。

5.把Length和Find改为虚函数。

以上链接通过。

6.BC的运行过程。

●IDE下运行无结果。

●直接运行提示出错:

找不到DLL

●Project–》options-》C++(SharedOptions)->

将Finaloutput设定为Dll所在位置:

../Debug

●代码:

ffdfd"

intlen=pFS->

Length();

ShowMessage(AnsiString(len));

7.Length或者Find的执行情况:

执行结果不正确,将其改为_stdcall执行结果正常

8.此时可以取消对类的输出。

即服务器端删除掉__declspec(dllexport)

Bc客户仍可正常执行。

9.对数据的敏感性:

客户编译器与服务器编译器同时依赖于同一个c++类定义,

在类的定义部分:

加上:

Public:

inta;

intb;

构造函数中:

a=2;

b=5;

以此文件生成dll,

客户端输出:

ShowMessage(AnsiString(pFS->

a));

ShowMessage(AnsiString(pFS->

b));

以此文件生成客户。

得到版本1.

改变a,b的定义顺序。

生成dll和客户。

得到版本2.

打乱客户和dll的搭配关系。

A和b的值都将颠倒。

实际上是一个显示的交叉转换过程。

10.于函数也有如上特性对虚拟函数的敏感性:

定义两个虚函数:

virtualintfa();

virtualintfb();

分别实现之。

编译服务器端和客户端。

改变定义顺序:

virtualintfa();

编译服务器端和客户端。

打乱版本的搭配顺序,调用将出现错乱。

11.对普通函数的不敏感性:

这里客户要用同种编译器,即vc

对于以上的虚函数,改为非虚的。

打乱次序后,调用不会出错。

说明是通过名字解析的方式进行的。

12.所以要对接口进行抽象。

降低耦合性。

添加接口类:

IFastString

头文件:

classIFastString

{

public:

virtualint_stdcallLength(void)=0;

virtualint_stdcallFind(char*psz)=0;

~IFastString();

IFastString();

};

实现文件:

IFastString.h"

IFastString:

IFastString(void)

~IFastString(void)

实现类FastString.h中:

classFastString:

publicIFastString

……

CreateObject的返回值改为IFastString

其声明:

__declspec(dllexport)IFastString*CreateObject(char*psz);

放到接口头文件中。

客户端代码改为:

IFastString*pFS=CreateObject("

fddfd"

13.因为接口中已经没有数据,所以自然不存在数据的敏感性。

14.在vc客户端,使用delete进行内存释放:

验证普通析构函数会出现内存泄漏。

验证方法:

⏹接口类重新向外输出__declspec(dllexport)

⏹子类分配大量内存。

IFastString*pFS=CreateObject("

deletepFS;

boolb=_CrtDumpMemoryLeaks();

//监控函数

b<

⏹b为1,表示有泄漏。

⏹或者使用windows任务管理器等监控机构。

15.对以上使用虚析构函数,代码为:

classIFastString

IFastString(void);

virtual~IFastString(void);

virtualint__stdcallLength(void)=0;

//返回该字符串的长度

virtualint__stdcallFind(char*psz)=0;

//查找指定的子串

注意此时既然使用虚析构,则不用输出接口类了。

验证vc客户端内存泄漏消失。

16.验证在bc客户端,仍然对析构函数链接失败。

intlen=pFS->

deletepFS;

析构函数位置不同而产生链接失败。

17.接口改为如下形式:

●取消输出

●增加Delete虚函数。

●采用默认的构造和析构函数。

virtualvoid_stdcallDelete()=0;

delete的实现:

voidFastString:

Delete()

deletethis;

}

18.BC客户端改为:

IFastString*pIFS=CreateObject("

intres=pIFS->

ShowMessage(AnsiString(res));

pIFS->

Delete();

通过。

19.对接口进行改变

virtualint_stdcallFindN(char*psz,intn)=0;

FastString实现新函数。

客户端对其进行调用。

生成版本2.

打乱版本1和2搭配次序。

●老客户用新对象,正常。

●新客户用老对象,失败。

20.增加新的接口:

classIPO

virtualvoid_stdcallDelete()=0;

virtualvoid_stdcallSave()=0;

多重继承:

classFastString:

publicIFastString,publicIPO

客户端:

IPO*pIPO=dynamic_cast<

IPO*>

(pIFS);

验证

●VC在接口之间可以正常运行。

IFastString*pIFS=CreateObject("

intres=pIFS->

IPO*pIPO=dynamic_cast<

pIPO->

Save();

deletepIFS;

●BC客户端运行异常

21.中性的类型转换

接口改为如下形式:

增加dynamic函数。

classIEO

virtualvoid_stdcallDynamic(char*name,void**ppI)=0;

classIFastString:

publicIEO

classIPO:

publicIFastString,publicIPO

实现方式:

voidFastString:

Dynamic(char*name,void**ppI)

if(strcmp(name,"

IFastString"

)==0)

*ppI=(IFastString*)this;

elseif(strcmp(name,"

IPO"

*ppI=(IPO*)this;

IEO"

调用方式:

IPO*pIPO;

IEO*pIEO;

Dynamic("

(void**)&

pIPO);

pIPO->

pIEO);

22.验证多接口之间的紧密耦合性。

略。

23.引用计数。

改写接口,为以上对象添加引用计数功能

实验心得

上机课有些手忙脚乱,安装软件时也遇到各种未知问题……但一切都井然有序地进行着。

做实验最大的难题,是需要先弄懂一个关键,WHY——为什么我们要做这个实验,即这个实验的目的是什么。

弄通目标之后,接下来的实验就进行得轻松愉快了。

最重要的一句话“因为跨平台,所以VC和BC下引用DLL的效果可能不一样。

XX,也让我们的实验显得容易很多。

善于使用搜索引擎也是益处多多的。

比如搜索一下“C++Builder的开发指南”,就会发现很多跨平台的例子。

这个会大大帮助我们理解实验,使实验顺利地进行下去。

实验报告毕竟是份文档,如果能把实验者自己的想法、截图的方式和报告的书写,沉淀为更加规范的格式,那想必是份完美的文档。

分布式不是一门很好理解的课程,但老师能从上课、完美翻译的参考书、实验、作业等一系列方式让我们多方位地理解这门课,我们是受益匪浅的。

最后,感谢老师辛苦的授课!

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 城乡园林规划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1