📄 orbit-prog.html
字号:
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=GB2312">
<TITLE>ORBit progamming</TITLE>
</HEAD>
<BODY>
<P><A HREF="Corba-prog.html">上一页</A>
<A HREF="Gnome-prog.html">下一页</A>
<P><B><FONT SIZE=+3>Orbit编程的基本方法</FONT></B><P>
<P><B><FONT SIZE=+2>CORBA程序的工作流程</FONT></B><P>
<P><LI>定义你的对象和方法:使用IDL</LI><P>
<P><LI>Client调用你定义的对象方法</LI><P>
<P><LI>调用被ORB传递到Server</LI><P>
<P><LI>Server真正调用你的方法</LI><P>
<P><LI>结果沿原路返回</LI><P>
<P><B><FONT SIZE=+2>工作流程的一些细节</FONT></B><P>
<P><B>1. Server启动,等待来自Client的请求</B><P>
<UL><LI>Server启动后,它首先生成一个POA(potable object adapter)。然后告诉POA他所能提供的服务,即Servant(Server按照IDL定义所实现的每个对象)。
<LI>Server从POA处得到每个Servant的引用OR(Object Reference,类似于句柄)。</LI><BR>
<LI>Server把自己提供的服务公布出来,这里有两个办法:</LI><P><UL><LI>将OR转换为一个字符串并输出;</LI><BR>
<LI>将这个OR绑定到一个简单易理解的名字上,这通过Naming Service完成。</LI><BR>
</UL>
<P>如图所示:<P><CENTER><IMG SRC=poa-register.gif><P>图1:Server启动并注册服务</CENTER><P>
</UL>
<P><B>2. Client调用你定义的对象方法</B><P>
<UL><LI>Client通过象Naming Service查询获得要访问的对象的引用OR(object reference),或通过一个IOR字符串获得;</LI><BR>
<LI>Client通过这个引用调用对象的方法,因为OR中有足够的信息来定位一个对象;</LI><BR>
<LI>这个调用被传递给ORB。</LI><BR><P>如图所示:
<P><CENTER><IMG SRC=poa-request-1.gif><P>图2:一个Client发出请求</CENTER><P>
</UL>
<P><B>3. 调用的完成</B><BR>
<P><UL>
<LI>Client端的调用请求通过ORB被传递给正确的Server端的ORB,定位是根据OR实现的;</LI><BR>
<LI>这个ORB把调用请求交给真正的Server进行处理;</LI><BR>
<LI>Server又根据OR定位产生这个OR的POA,并把请求传给它;</LI><BR>
<LI>POA又把请求传给最后真正的Servant,完成调用并返回。</li><BR>
<BR><P>如图所示:
<P><CENTER><IMG SRC=poa-request-2.gif><P>图2:Server对请求进行服务</CENTER><P>
</UL>
<P><B><FONT SIZE=+2>ORBit程序的编译</FONT></B><P>
其实问题比上面讲的还要复杂的多。为了在GNOME上编程,我们至少还需要了解stub和skeleton的概念。<P>
<LI>stub:为了保证一个CORBA的实现是通用的,其接口是按IDL定义的CORBA对象,任何语言只要符合CORBA标准都能访问。因此C语言编写的Clients是无法直接访问的并调用某个远程对象的方法的。解决的办法就是在Client和ORB间加一个模块stub。stub的作用是把Client的请求转换为正确的标准的消息传递给ORB。它就象是远程对象在本地的一个代表或曰“代理”。这样才能使得对远地对象的操作就象在本地一样。</LI><P>
<LI>skeleton:skeleton的作用与stub相反,就是在对象所在地替Client完成调用。<P>
stub和skeleton的实现是程序员的事,但实际上这个工作大多数情况下是由IDL的编译器完成的。不同的语言需要使用不同的编译器。一个IDL的编译器甚至可以替程序员生成Servant的程序框架,而程序员只需填写自己的内容即可。
<P><B><FONT SIZE=+1>举例说明</FONT></B><P>
<P><B>echo-skels.c</B><P>
<PRE>
/*
* This file was generated by orbit-idl - DO NOT EDIT!
*/
#include <string.h>
#include "echo.h"
#define GET_ATOM(x) G_STMT_START{ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->decoder(&x, (GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur), sizeof(x)); GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = ((guchar *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) + sizeof(x); }G_STMT_END
void
_ORBIT_skel_Echo_echoString(POA_Echo *_ORBIT_servant,
GIOPRecvBuffer *_ORBIT_recv_buffer,
CORBA_Environment *ev,
void (*_impl_echoString)(PortableServer_Servant servant,
const CORBA_char * input,
CORBA_Environment *ev))
{
CORBA_char * input;
GIOPSendBuffer *_ORBIT_send_buffer;
if(giop_msg_conversion_needed(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer))) {
/* demarshal parameter input */
{
GIOP_unsigned_long len;
GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = ALIGN_ADDRESS(GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur, 4);
GET_ATOM(len);
input = len?(GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur):(((char *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) - sizeof(CORBA_unsigned_long)); GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = ((guchar *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) + len;
}
} else {
/* demarshal parameter input */
{
GIOP_unsigned_long len;
GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = ALIGN_ADDRESS(GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur, 4);
len = *((CORBA_unsigned_long *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur);
GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = ((guchar *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) + sizeof(CORBA_unsigned_long);
input = len?(GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur):(((char *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) - sizeof(CORBA_unsigned_long)); GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = ((guchar *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) + len;
}
}
_impl_echoString(_ORBIT_servant, input,
ev);
_ORBIT_send_buffer =
giop_send_reply_buffer_use(GIOP_MESSAGE_BUFFER(_ORBIT_recv_buffer)->connection, NULL,
_ORBIT_recv_buffer->message.u.request.request_id,
ev->_major);
if(ev->_major == CORBA_NO_EXCEPTION) {
} else if(ev->_major == CORBA_SYSTEM_EXCEPTION)
ORBit_send_system_exception(_ORBIT_send_buffer, ev);else if(ev->_major == CORBA_USER_EXCEPTION)
ORBit_send_user_exception(_ORBIT_send_buffer, ev, NULL); giop_send_buffer_write(_ORBIT_send_buffer);
giop_send_buffer_unuse(_ORBIT_send_buffer);
}
static ORBitSkeleton get_skel_Echo(POA_Echo *servant,
GIOPRecvBuffer *_ORBIT_recv_buffer,
gpointer *impl)
{
gchar *opname = _ORBIT_recv_buffer->message.u.request.operation;
switch(opname[0]) {
case 'e':
*impl = (gpointer)servant->vepv->Echo_epv->echoString;
return (ORBitSkeleton)_ORBIT_skel_Echo_echoString;
break;
default: return NULL;
}
}
static void init_local_objref_Echo(CORBA_Object obj, POA_Echo *servant)
{
obj->vepv[Echo__classid] = servant->vepv->Echo_epv;
}
void POA_Echo__init(POA_Echo *servant,
CORBA_Environment *env)
{
static const PortableServer_ClassInfo class_info = {(ORBit_impl_finder)&get_skel_Echo, "IDL:Echo:1.0", (ORBit_local_objref_init)&init_local_objref_Echo};
PortableServer_ServantBase__init(((PortableServer_ServantBase *)servant), env);
ORBIT_OBJECT_KEY(servant->_private)->class_info = (PortableServer_ClassInfo*) &class_info;
if(!Echo__classid)
Echo__classid = ORBit_register_class(&class_info);
}
void POA_Echo__fini(POA_Echo *servant,
CORBA_Environment *env)
{
PortableServer_ServantBase__fini(servant, env);
}
</PRE>
<P><B>echo-stubs.c</B><P>
<PRE>
/*
* This file was generated by orbit-idl - DO NOT EDIT!
*/
#include <string.h>
#include "echo.h"
#define GET_ATOM(x) G_STMT_START{ GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->decoder(&x, (GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur), sizeof(x)); GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur = ((guchar *)GIOP_RECV_BUFFER(_ORBIT_recv_buffer)->cur) + sizeof(x); }G_STMT_END
void
Echo_echoString(Echo _obj,
const CORBA_char * input,
CORBA_Environment *ev)
{
GIOP_unsigned_long _ORBIT_request_id;
GIOPSendBuffer *_ORBIT_send_buffer;
GIOPRecvBuffer *_ORBIT_recv_buffer;
static const struct { CORBA_unsigned_long len; char opname[11]; } _ORBIT_operation_name_data = { 11, "echoString" };
static const struct iovec _ORBIT_operation_vec = {(gpointer)&_ORBIT_operation_name_data, 15};
GIOPConnection *_cnx;
if(_obj->servant && _obj->vepv && Echo__classid)
{
((POA_Echo__epv *)_obj->vepv[Echo__classid])->echoString(_obj->servant, input, ev);
return;
}
_cnx = ORBit_object_get_connection(_obj);
retry_request:
_ORBIT_request_id = giop_get_request_id();
if((_cnx == NULL) || (_obj->active_profile == NULL)) {
CORBA_exception_set_system(ev, ex_CORBA_COMM_FAILURE, CORBA_COMPLETED_NO);
return;
}
_ORBIT_send_buffer =
giop_send_request_buffer_use(_cnx, NULL,
_ORBIT_request_id, CORBA_TRUE, &(_obj->active_profile->object_key_vec),
&_ORBIT_operation_vec, &ORBit_default_principal_iovec);
if(!_ORBIT_send_buffer) {
CORBA_exception_set_system(ev, ex_CORBA_COMM_FAILURE, CORBA_COMPLETED_NO);
return;
}
/* marshal parameter input */
{
GIOP_unsigned_long len = input?(strlen(input)+1):0;
giop_message_buffer_do_alignment(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), 4);
giop_send_buffer_append_mem_indirect(GIOP_SEND_BUFFER(_ORBIT_send_buffer), &len, sizeof(len));
if(input)
giop_message_buffer_append_mem(GIOP_MESSAGE_BUFFER(_ORBIT_send_buffer), input, len);
}
giop_send_buffer_write(_ORBIT_send_buffer);
giop_send_buffer_unuse(_ORBIT_send_buffer);
_ORBIT_recv_buffer = giop_recv_reply_buffer_use_2(ORBit_object_get_connection(_obj), _ORBIT_request_id, TRUE);
if(_ORBIT_recv_buffer == NULL || _ORBIT_recv_buffer->message_buffer.message_header.message_type != GIOP_REPLY) {
CORBA_exception_set_system(ev, ex_CORBA_COMM_FAILURE, CORBA_COMPLETED_MAYBE);
if(_ORBIT_recv_buffer) giop_recv_buffer_unuse(_ORBIT_recv_buffer);
return;
}
if(_ORBIT_recv_buffer->message.u.reply.reply_status != GIOP_NO_EXCEPTION) {
if(_ORBIT_recv_buffer->message.u.reply.reply_status == GIOP_LOCATION_FORWARD) {
if(_obj->forward_locations != NULL)
ORBit_delete_profiles(_obj->forward_locations);
_obj->forward_locations = ORBit_demarshal_IOR(_ORBIT_recv_buffer);
_cnx = ORBit_object_get_forwarded_connection(_obj);
giop_recv_buffer_unuse(_ORBIT_recv_buffer);
goto retry_request;
} else {
ORBit_handle_exception(_ORBIT_recv_buffer, ev, NULL,_obj->orb);
giop_recv_buffer_unuse(_ORBIT_recv_buffer);
return;
}
}
giop_recv_buffer_unuse(_ORBIT_recv_buffer);
ev->_major = CORBA_NO_EXCEPTION;
}
</PRE>
在IDL编译器编译一个IDL文件时,同时生成一些头文件和必须的C文件,在用C编译器编译生成Client和Server的可执行程序时,需将这些文件同时编译链结。
<P><B>Makefile</B><P>
<PRE>
CC = gcc
ORBIT_IDL = /usr/bin/orbit-idl
ORBIT_CFLAGS = -I/usr/lib/glib/include -I/usr/include
ORBIT_LIBS = -L/usr/lib -lORBit -lIIOP -lORBitutil -lglib -lnsl -lm
CFLAGS = $(ORBIT_CFLAGS)
LFLAGS = $(ORBIT_LIBS)
all : idltargets echo-client echo-server
echo-client : echo-client.o echo-common.o echo-stubs.o
$(CC) -o echo-client echo-client.o echo-stubs.o echo-common.o -lIIOP -lORBit -lORBitutil $(LFLAGS)
echo-server : echo-server.o echo-skels.o echo-common.o
$(CC) -o echo-server echo-server.o echo-skels.o echo-common.o -lIIOP -lORBit -lORBitutil $(LFLAGS)
clean :
rm *.[oa] echo-client echo-server
real-clean : clean
rm echo-stubs.[oc] echo-skels.[oc] echo.h echo-common.[oc]
#
# IDL compiler rules
#
# all in one shot
idltargets : echo.idl
$(ORBIT_IDL) echo.idl
# individual rules
echo-stubs.c : echo.idl
$(ORBIT_IDL) echo.idl
echo-common.c : echo.idl
$(ORBIT_IDL) echo.idl
echo-skels.c : echo.idl
$(ORBIT_IDL) echo.idl
echo-client.c : echo.h
echo-server.c : echo.h
echo.h : echo.idl
$(ORBIT_IDL) echo.idl
</PRE>
<P>
<P><A HREF="Corba-prog.html">上一页</A>
<A HREF="Gnome-prog.html">下一页</A>
<P>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -