建立一个CORBA客户端
当你写一个CORBA客户时,第一步是确定客户程序可以与客户机上的ORB软件交谈。要做到这一点,使用CORBA Client wizard。选择File|New并从New Item对话框的Multitier页选择标签为CORBA Client的图标。这个向导让你说明是想建立一个控制台应用程序或是一个窗口应用程序。
正如CORBA服务器程序,你可以指定CORBA客户是否使用VCL类。如果不选VCL复选框,所有生成的代码均可被移植到其它平台上。
在CORBA Client wizard中加入任何所有定义了你想用的服务器对象界面的IDL文件。但也可以不使用任何IDL文件而建立CORBA客户应用程序(确切的说是加入一个生成客户单元到工种中)。这不是首选的方法。当工程包含服务器界面的IDL文件时,你可以用该向导来绑定到服务器上的对象上。
注意:如果你开始CORBA客户工程时没有加入IDL文件,还可以在任何时候用Project|Add to Project加入它。
CORBA Cleint wizard总是建立指定类型的客户端工程,将CORBA库加进工程文件并加入以下起动代码以初始化ORB(Object Request Broker对象请求代理)。
CORBA::ORB_var orb= CORBA::ORB_init(argc,argv);
如果你想通过CORBA服务器的CALLBACK界面的话,要在客户程序中初始化BOA(基本对象配适器)。只要在向导中选上适当的框就可以做到了。 下步,用和写其它CBuider应用程序相同的方法进行应用程序编写。不过,当你使用定义在服务器应用中的对象的时候,不是直接和对象实例打交道,而是取得一个对CORBA对象的引用并使用它来工作。有两种方法可以取得对服务器对象的引用,这和你用哪种绑定相关:
如果使用静态绑定,你可以调用CORBA Object wizard(Edit|Use CORBA Object)。静态绑定比动态快,并且提供编译时类型检查、代码完整(code_completion)等好处。
然而,总有你要到运行时才知道想用的界面或对象的时候,这时就要用动态绑定了。动态绑定使用一个通用的CORBA对象,它用一种名为ANY的特殊CORBA类型将请求传给服务器。
使用存根
存根类是在编译IDL文件时自动生成的。他们定义在生成的客户端文件里,这些文件名字为xxx_c.cpp和xxx_c.hh。
注意:可以让C++BUILDER只建立客户文件(存根)而不要服务器文件,这要通过Project Options对话框的CORBA页来设定。
当写一个CORBA客户端时,不必编辑生成的客户端文件里的代码,相反,在用到时实例化存根类。这要通过选择Edit|Use CORBA Object调出Use CORBA Object wizard。
在这个对象使用向导中,指明包含所需界面的IDL文件,并选择要用的界面。如果只想绑定到特定名字的CORBA对象实例,可以可选的提供一个名字给CORBA对象。
Use CORBA Object wizard让你从以下绑定机制中选择:
如果客户端程序是VCL可用型的窗口应用程序,可以在程序窗体(form)中创建一个属性保存你的CORBA对象存根类的一个实例。你可以把这个属性当作CORBA服务器对象的实例来用。
如果建立的是控制台应用程序,向导会在你的main()函数里作为变量来示例存根类。相似的,它可以把存根类示例为WinMain()中的变量,如果是窗口应用程序的话。
不管是Windows还是Console应用,向导可以把一个属性(property)加入到任何指定单元中的某个类中或起草一个含有一个代表存根实例属性的新类。
不管用哪种机制,向导加入必要的头文件并生成代码,这些代码绑定一个CORBA服务器对象的存根变量或属性。例如,下边的代码在控制台程序的main()中示例了名为MyServerObj的服务器界面的存根。
#include <corba.h>
#include <condefs.h>
#include MyServerObj_c.hh?
#pragma argsused
int main(int argc, char* argv[])
{
try
{
// Initialize the ORB
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
MyServerObj_var TheObject = MyServerObj::_bind(\"InstanceName\");
}
catch(const CORBA::Exception& e)
{
cerr << e << endl;
return(1);
}
return 0;
}
注意:如果拷贝绑定代码到程序的其它部分,要确保存根变量是局域变量或类的数据成员。不要使用全局存根变量,因为它们在orb变量释放前不释放他们的CORBA引用计数。如果非要用全局存根变量,务必在orb释放之前将变量设为NULL以解除绑定。
如果你的客户应用程序只包括生成的客户单元(xxx_c),就不能用CORBA Object wizard绑定到服务器对象。相反要自己动手写这些代码。你也许想写自己的绑定代码以利用VisiBroker的绑定选项。(例如:可以指定特定的服务器,禁止CORBA连接丢失时的自动重绑定服务器特性,等等)。详情见VisiBroker文档。
使用动态请求界面(DII)
dynamic invocation itnerface(DII)允许客户端应用调用服务器对象,而且不使用明确套接(marshal)界面调用的存根类。因为DII必须在客户发送请求之前编码所有类型信息及解码服务器的信息,所以要比用存根类慢。
要在客户端应用中使用DII,必须:
1、建立一个公用CORBA对象,它的作用类似于存根对象,除了其实现中不包含套接请求。必要提供对象的响应ID以说明哪个对象将收到DII请求:
CORBA::Object_var diiObj;
try
{
diiObj = orb->bind(\"IDL:ServerObj:1.0\");
} catch (const CORBA::Exception& E)
{
// handle the bind exception.
}
2、接着,用这个公用CORBA对象为其代表对象的特定方法建立一个请求对象:
CORBA::Request_var req= diiObj->_request(\"methodName\");
3、下面,加上该方法的所有参数。参数被加到类型为CORBA::NVList_ptr的请求(request)上。每个参数都是CORBA::Any类型的,Any类就似于BCB Variant。要求CORBA::Any类型是因为一个有名字值清单(CORBA::nvlIST)必须管理任何参数清单,其中可能包括任何类型的值。
CORBA::Any arg;
arg <<=(const char *)\"argvalue\";
CORBA::NVList_ptr arguments=req->arguments();