Orbit编程的基本方法
CORBA程序的工作流程
工作流程的一些细节
1. Server启动,等待来自Client的请求
如图所示:
图1:Server启动并注册服务
2. Client调用你定义的对象方法
如图所示:
图2:一个Client发出请求
3. 调用的完成
如图所示:
图2:Server对请求进行服务
ORBit程序的编译
其实问题比上面讲的还要复杂的多。为了在GNOME上编程,我们至少还需要了解stub和skeleton的概念。
stub和skeleton的实现是程序员的事,但实际上这个工作大多数情况下是由IDL的编译器完成的。不同的语言需要使用不同的编译器。一个IDL的编译器甚至可以替程序员生成Servant的程序框架,而程序员只需填写自己的内容即可。
举例说明
echo-skels.c
/* * This file was generated by orbit-idl - DO NOT EDIT! */ #include#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); }
echo-stubs.c
/* * This file was generated by orbit-idl - DO NOT EDIT! */ #include在IDL编译器编译一个IDL文件时,同时生成一些头文件和必须的C文件,在用C编译器编译生成Client和Server的可执行程序时,需将这些文件同时编译链结。#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; }
Makefile
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