⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 orbit-prog.html

📁 这是一个介绍 linux 编程知识的文章。
💻 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 + -