BCB环境下CORBA实做之自己动手

品雪
1999.4
http://pinxue.yeah.net

建立一个CORBA服务器    建立一个CORBA客户端    让它们通信


建立一个CORBA服务器

记不得清步骤了:-(。又去看了看,要以下几步。

  1. 设计Server对象界面

就是建立一个IDL文件。这也就是说,要先设计好服务器的对象结构,不过好在BCB可以根据IDL文件的修改自动更新其它生成代码,问题不大。俺且做一个最简单的吧:服务器对象界面为StockServer,该对象只有一个string getName();方法。将来客户可以调用它取得TCorbaTestObj名字。

//testobj.idl
interface StockServer{
string getName();
};

俺把它存在projects\tstcorbaobject\testobj.idl里。以后都在这个目录里工作。
注意最后那个";"一定要写!不然编译会出错。这是IDL,不是C++。

2、使用CORBA server wizard建立服务器应用程序

File | New,再下面的对话框中选Multitier, CORBA Server
New Items

接着,在Wizard里选Windows Application,并用Add...加入testobj.idl
CORBA Server Wizard

OK,自动生成Project1.cpp。将它存为testserver.cpp
刚才在bcb5+vbroker4下试了一下,发现同时生成有form1,第一个对话框问的是unit1的文件名字,随便给一个好了,可不要弄混了或者取同样的名字哟。 2000.3.29

3、编译包含界面定义的IDL文件,得到框架及存根。

切换到testobj.idl(该文件如果没在编辑窗里就用Ctrl+Alt+F11,再双击这个文件打开),选Project|Compile Unit。

这时,发生了一个小故障:Fail to run IDL2CPP.EXE,系统找不到文件。幸好我记得俺的VisiBroker3.3 for C++装在D:\Visibroker33里,这个文件在bin目录里,于是到我的电脑,属性里找到环境页(NT4),在CLASSPATH里加上d:\vsbroker33\lib\vbcpp.jar,在PATH里加上d:\vsbroker33\bin;d:\vsbroker33\jre\bin;确定即可,不用重启。

编译之后,代码编辑窗又多出两页来:testobj_s.cpp(框架)和testobj_c.cpp(存根)。

4、用CORBA object wizard定义(并实现)实现类。

“实现”挺拗口的,有时是动词有时是形容词:

所以现在,俺要生成实现类(就是那个空壳子)。

File|New,从对话框的mutitier页中选择CORBA Object Implementation图标,过一小会就见:
CORBA Object Implement wizard

IDL文件里那个就是我想用的,如果不是还可以用...去选。

Interface Name嘛,这会只有一个可用就是StockServer。

实现类的单元名字,StockServerServer也挺好,就不改了。

类名字就用它默认的好了。

起始时在main()里实例化对象好了,这个对象实例名字就叫StockServerObject好了。多个实例(按...加入)就以后再试好了,现在且走着。

OK之后,代码编辑窗口里又开了一页:StockServerServer.cpp

5、 完成4建立的类实现CORBA对象

在StockServerServer.cpp里底部的getName(){}里加一句,使之成为:

char* StockServerImpl::getName()
{
return "CorbaServerTester";
}

Project Make之,会有一个warning。俺猜那个定义但未使用的变量是用来处理入口参数的。

好了,Server制作完成。慢来慢来!F9了一下,居然,Exception!

忘了,还得要注册IDL文件呢!不对呀,明明说不是必需的嘛,先试试。

不灵!

现存怀疑是Delphi所带3.2与CBuilder的3.3互相干扰,于是用移去3.2用3.3取代其目录,不灵!

没招了,于是打开一个VBroker3.3 for c++带的例子试试,哈哈,还是不灵!

这就不是程序的问题了,看来是VBroker的问题了。

不对不对,俺在IDE之外运行俺的SERVER和VBroker3.3的Account Server都好好的,不过测试篇说的Test工具一个对象也找不到。又看了看VisiBroker的说明,要求在win下用start xxx来启动,为什么不直接运行xxx?谁能告诉我

为什么?!

先不管了,反正服务器是做好了。


建立一个CORBA客户端

俺已经晕了,客户端怎么做来着?

幸好昨天已经把文档翻译过来了,瞄了一眼,如果用静态绑定的话就只要运行两个向导就成:CORBA Client wizard和Use CORBA Object wizard。

那就干吧。咱们做一个使用VCL的客户,调用Server对象的getName方法,并将结果显示在Form的Edit里。

1、File|New, Multitier,CORBA Client wizard:
CORBA Client Wizard

别的不动它,用Add...把testobj.idl加上。

OK。之后Project1工程生成,把它存成testclient,unit1存成clientmain。

2、Edit|Use CORBA Object:
Use CORBA Object Wizard

如果IDL文件没有选好用...选上,俺这儿是自动加好了。

Interface Name嘛,IDL文件里也定义了StockServer,所以只有它一个可选。

Object Name写什么呢?别慌,记得在服务器的CORBA Object Implementation wizard里指定过来着,是StockServerObject,就写它。绑定机制显然要用Use in Form才方便,Form名字就懒得改了。

OK,向导自动修改了俺的clientmain.cpp/h,加入带stockServer属性(__property)的TForm1类的实例Form1。

加上删除线的说明有点问题,应该是:

当调用过Edit|Use Corba Object之后,bcb会自动将
USEUNIT("..\testobj_c.cpp");
USEUNIT("..\testobj_s.cpp");
加到testclient(project的主程序)里,前面指定的idl文件里的接口对client就可用了。我猜想如果这个时候idl文件还没有被编译,bcb应该会自动用idl2cpp去编译吧。

然后bcb会弹出一个对话框,让程序员从里边选择使用哪个接口及该接口实现类的哪个实例,并可以指定一个对象名,这个名字将做为参数传给服务器上该对象类的建构函数,从而会在服务器端生成一个该名字的对象实例,如果对象名为空白,那么client将会使用boa提供的任何一个对象实例。

//-----------题外话-----------
在BCB5+VBroker4的环境下,从源代码分析得知,接口实现类的建构函数只是把这个参数传给父类_sk_StockServer的建构函数而矣,这个类是在编译idl时生成的testobj_s.hh里定义的,_sk_StockServer() 再把参数传给PortableServer_ServantBase类的_object_name方法。PortableServer_ServantBase类定义在poa_c.hh里,具体在_object_name里都发生了些什么则是属于vbroker的运行机制了,目前还没搞清楚。
注意,POA是对象实现与ORB之前的中介,是VBroker4带来的新东西,它的地位相当于VBroker3时代的BOA。详情请看VBroker4的文档或CORBA新版的文档。
如果使用vbroker4进行corba应用开发的话,建议先把它的联机文档读一下,应为vbroker4实现的是corba2.3,有很多概念上的变化,而且联机文档对于corba的概念、VBroker的体系和原理、VBroker4下开发服务器与客户端的步骤都有详细讲解,在把这些理解之后再依本文的方法做bcb下的可视开发,就不会对wizard生成的那些古怪的代码感到迷惑了。嘻嘻,不要问我,我还没有看过,知道的都写在这里了。:-)
//-----------题外结束---------

BCB的Use Corba Object Wizard可以自动完成在client里调用server上的corba object所需的准备工作,它可以通过Form的property、main()中的变量、class的成员来封装对服务器对象的引用。如果分析每种情况生成的代码,它最终都是通过以下几步完成任务的:
1、定义一个~_var变量:StockServer_var FstockServer;
2、将变量绑定到一个对象实例上:FstockServer = StockServer::_bind();
注意,在Form和main()里使用时,绑定是由wizard生成的代码自动完成的,而在class里使用时你可以选择wizard是否生成绑定代码、是否自动引用生成绑定代码。

2000.3.29.

3、完成程序功能。

对这个测试程序来说简单得很,在Form1上放一个Button1一个Edit1,把标题文字改一下:
Client Form1

双击这个按钮,写上响应代码:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Edit1->Text=stockServer->getName();
}
4、测试。(本地)

然后,File|Save All,再F9之,哈哈第一个CORBA程序运行成功了:
CORBA Client Run Result

注意:记得在运行之前用start testserver.exe启动服务器哟。
没有必要用start ...,直接运行就可以了 2000.3.29.

5、网络测试。按俺的理解,把客户拷贝到其它计算机上运行就可以了,待俺试来。

哈哈,在客户端要有这么几个支持文件就可以:cp3245mt.dll orb_br.dll borlndmm.dll,还不知道是干什么用的。

注:开发环境为PWinNT4 WS+SP3,网络测试在PWinNT4 WS及Win95 OSR2测试成功,编译选项使用release配置时,Win95在缺少dll时提示程序启动出错,而NT则提示断言失败,如果编译时用debug配置会告诉你缺哪个dll。


大功告成!