CPP实现CORBA静态绑定(八)

  • CORBA基本架构
  • IDL文件编写
  • CPP示例实现(上)
  • CPP示例实现(下)
  • C示例实现(IOR+NS上)
  • C示例实现(IOR+NS下)
  • C示例实现(IOR上)
  • C示例实现(IOR下)

然后完成客户端部分:
Hi-client-ior.c

#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <orbit/orbit.h>

#include "Hi.h"

/*
Usage: ./hi-client_ns
*/

/**
 * test for exception
 */
static
gboolean
raised_exception(CORBA_Environment *ev)
{
	return ((ev)->_major != CORBA_NO_EXCEPTION);
}

/**
 * in case of any exception this macro will abort the process
 */
static
void
abort_if_exception(CORBA_Environment *ev, const char* mesg)
{
	if (raised_exception (ev)) {
		g_error ("%s %s", mesg, CORBA_exception_id (ev));
		CORBA_exception_free (ev);
		abort();
	}
}


/*
 * main
 */
int main(int argc, char* argv[])
{
	CORBA_ORB orb=CORBA_OBJECT_NIL;
	CORBA_Environment ev;
	HiCorba_Hi service = CORBA_OBJECT_NIL;

	//init orb
	g_print("\nClient>starting client...");
	g_print("\nClient>creating and initializing the ORB");
	CORBA_exception_init(&ev);
	abort_if_exception(&ev, "CORBA_exception_init failed");
	orb=CORBA_ORB_init(&argc,argv,"orbit-local-orb",&ev);
	abort_if_exception(&ev, "CORBA_ORB_init failed");

	// read name_service ior from ns.ior 
	CORBA_char  filename[] = "service.ior";
 	FILE *file   = NULL;
	g_print("\nClient>reading the file '%s'",filename);
	if ((file=fopen(filename, "r"))==NULL)
                g_error ("could not open '%s'", filename);
	gchar objref[1024];
	fscanf (file, "%s", &objref);
	g_print("\nClient>getting the 'IOR' - from the file '%s'",filename);
	g_print("\nClient>the IOR is '%s'",objref);
        service = (HiCorba_Hi)CORBA_ORB_string_to_object(orb,objref,&ev);
	abort_if_exception(&ev, "CORBA_ORB_string_to_object 'NameService IOR' failed");

	// invoke service
	g_print("\nClient>calling the Hi service...");
	CORBA_char *msg=HiCorba_Hi_sayHiTo(service, "neohope", &ev);
	abort_if_exception(&ev, "HiCorba_Hi_sayHiTo failed");
        g_print("\nClient>server returned the following message: %s\n", msg);

	CORBA_Object_release(service, &ev);
	abort_if_exception(&ev, "release failed");

        if (orb != CORBA_OBJECT_NIL)
        {
           /* going to destroy orb.. */
           CORBA_ORB_destroy(orb, &ev);
	   abort_if_exception(&ev, "destroy failed");
	}

}

MakeClient

CC       = gcc
CFLAGS   = -c -g -pthread -D_REENTRANT -DORBIT2=1 \
           -I/usr/include/orbit-2.0 \
           -I/usr/include/glib-2.0 \
           -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
LDFLAGS  = -Wl,--export-dynamic -lORBit-2 -lORBitCosNaming-2 -lgmodule-2.0 \
           -ldl -lgobject-2.0 -lgthread-2.0 -lpthread -lglib-2.0 -lm \
           -L/usr/lib
ORBIT_IDL= /usr/bin/orbit-idl-2

all : Hi-client-ior.bin

Hi-client-ior.bin : Hi-common.o Hi-stubs.o Hi-client-ior.o
	$(CC) $(LDFLAGS) Hi-common.o Hi-stubs.o Hi-client-ior.o -o Hi-client-ior.bin

%.o : %.c 
	$(CC) $(CFLAGS) $< -o $@ 

nidl : Hi.idl
	$(ORBIT_IDL) Hi.idl
	$(ORBIT_IDL) --skeleton-impl Hi.idl

clean:
	rm -rf *.bin
	rm -rf *.o

编译

Make -f MakeClient

运行

#首先运行orbd
orbd -ORBInitialPort 1900
 
#然后运行server
./Hi-server-ior.bin
Server>starting server...
Server>creating and initializing the ORB
Server>getting reference to RootPOA
Server>activating the POA Manager
Server>creating the servant
Server>writing the file 'service.ior'
Server>writing the IOR to file 'service.ior'
Server>running the orb...
Server>server is returning: Hi, neohope !
 
#然后运行client
./Hi-client-ior.bin
Client>starting client...
Client>creating and initializing the ORB
Client>reading the file 'service.ior'
Client>getting the 'IOR' - from the file 'service.ior'
Client>the IOR is 'IOR:010000001300000049444c3a4869436f7262612f48693a312e300000030000000054424f580000000101020005000000554e4958000000000a0000006c6f63616c686f73740000002d0000002f746d702f6f726269742d6e656f686f70652f6c696e632d316235362d302d376663653334336261303164360000000000000000caaedfba58000000010102002d0000002f746d702f6f726269742d6e656f686f70652f6c696e632d316235362d302d37666365333433626130316436000000001c00000000000000dbcce0b85e73a828c02b2828282828280100000060aa3a1a01000000480000000100000002000000050000001c00000000000000dbcce0b85e73a828c02b2828282828280100000060aa3a1a01000000140000000100000001000105000000000901010000000000'
Client>calling the Hi service...
Client>server returned the following message: Hi, neohope !

CPP实现CORBA静态绑定(七)

  • CORBA基本架构
  • IDL文件编写
  • CPP示例实现(上)
  • CPP示例实现(下)
  • C示例实现(IOR+NS上)
  • C示例实现(IOR+NS下)
  • C示例实现(IOR上)
  • C示例实现(IOR下)

在linux系统下,有很多开源的CORBA通讯框架,在C的示例中,使用了orbit的框架。
如我用的是Debian系统,可以直接安装:

apt-get install orbit2
apt-get install liborbit2-dev

安装后,可以通过工具orb-rdl-2从idl文件生成需要的stubs及skeletons接口代码:

#该命令会生成文件:Hi.h、Hi-common.c、Hi-skels.c、Hi-stubs.c
orbit-idl-2 Hi.idl

可以通过工具orb-rdl-2从idl文件生成服务端代码:

#该命令会生成模板文件:Hi-skelimpl.c
orbit-idl-2 --skeleton-impl Hi.idl

首先完成服务端部分:
Hi-server-ior.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <orbit/orbit.h>
#include "Hi.h"
#include "Hi-skelimpl.c"
/*
./Hi-server_ns -ORBInitRef NameService=[string of IOR of NameService]
*/

/**
 * test for exception 
*/
static
gboolean
raised_exception(CORBA_Environment *ev) {
	return ((ev)->_major != CORBA_NO_EXCEPTION);
}

/**
 * in case of any exception this macro will abort the process
*/
static
void
abort_if_exception(CORBA_Environment *ev, const char* mesg)
{
	if (raised_exception (ev)) {
		g_error ("%s %s", mesg, CORBA_exception_id (ev));
		CORBA_exception_free (ev);
		abort();
	}
}

/*
 * main
*/
int
main (int argc, char *argv[])
{
	PortableServer_POA poa;
	HiCorba_Hi servant = CORBA_OBJECT_NIL;
	CORBA_ORB orb=CORBA_OBJECT_NIL;
	CORBA_Environment ev;

	// init ORB
	g_print("\nServer>starting server...");
	g_print("\nServer>creating and initializing the ORB");
	CORBA_exception_init(&ev);
	abort_if_exception(&ev, "CORBA_exception_init failed");
	orb=CORBA_ORB_init(&argc,argv,"orbit-local-orb",&ev);
	abort_if_exception(&ev, "CORBA_ORB_init failed");

	// activate POA
	g_print("\nServer>getting reference to RootPOA");
	poa= (PortableServer_POA) CORBA_ORB_resolve_initial_references(orb,"RootPOA",&ev);
	abort_if_exception(&ev, "CORBA_ORB_resolve_initial 'RootPOA' failed");
	g_print("\nServer>activating the POA Manager");
	PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(poa, &ev),&ev);
	abort_if_exception(&ev, "POA_activate failed");

	// create servant
	g_print("\nServer>creating the servant");
	servant = impl_HiCorba_Hi__create (poa, &ev);
	abort_if_exception(&ev, "impl_HiCorba_Hi__create failed");
	
	// read name_service ior from ns.ior 
	CORBA_char  filename[] = "service.ior";
 	FILE *file   = NULL;
	g_print("\nServer>writing the file '%s'",filename);
	if ((file=fopen(filename, "w"))==NULL)
                g_error ("could not open '%s'\n", filename);
	gchar *objref = CORBA_ORB_object_to_string (orb, servant, &ev);
	abort_if_exception(&ev, "CORBA_ORB_object_to_string' failed");
        fprintf(file,"%s",objref);
        fflush(file);
        fclose(file);
	g_print("\nServer>writing the IOR to file '%s'",filename);
	
	// start 
	g_print("\nServer>running the orb...");
	CORBA_ORB_run(orb,&ev);
	abort_if_exception(&ev, "ORB_run failed");
}

Hi-skelimpl.c

/* This is a template file generated by command */
/* orbit-idl-2 --skeleton-impl Hi.idl */
/* User must edit this file, inserting servant  */
/* specific code between markers. */

#include <stdlib.h>
#include <stdio.h>
#include "Hi.h"

/*** App-specific servant structures ***/

#if !defined(_typedef_impl_POA_HiCorba_Hi_)
#define _typedef_impl_POA_HiCorba_Hi_ 1
typedef struct {
POA_HiCorba_Hi servant;
PortableServer_POA poa;
   /* ------ add private attributes here ------ */
   /* ------ ---------- end ------------ ------ */
} impl_POA_HiCorba_Hi;
#endif

/*** Implementation stub prototypes ***/

#if !defined(_decl_impl_HiCorba_Hi__destroy_)
#define _decl_impl_HiCorba_Hi__destroy_ 1
static void impl_HiCorba_Hi__destroy(impl_POA_HiCorba_Hi *servant,
CORBA_Environment *ev);
#endif

#if !defined(_decl_impl_HiCorba_Hi_sayHiTo_)
#define _decl_impl_HiCorba_Hi_sayHiTo_ 1
static CORBA_string
impl_HiCorba_Hi_sayHiTo(impl_POA_HiCorba_Hi *servant,
const CORBA_char * someone,
CORBA_Environment *ev);
#endif

#if !defined(_decl_impl_HiCorba_Hi_add_)
#define _decl_impl_HiCorba_Hi_add_ 1
static CORBA_long
impl_HiCorba_Hi_add(impl_POA_HiCorba_Hi *servant,
const CORBA_long numa,
const CORBA_long numb,
CORBA_Environment *ev);
#endif

#if !defined(_decl_impl_HiCorba_Hi_shutdown_)
#define _decl_impl_HiCorba_Hi_shutdown_ 1


static void
impl_HiCorba_Hi_shutdown(impl_POA_HiCorba_Hi *servant,
CORBA_Environment *ev);
#endif


/*** epv structures ***/

#if !defined(_impl_HiCorba_Hi_base_epv_)
#define _impl_HiCorba_Hi_base_epv_ 1
static PortableServer_ServantBase__epv impl_HiCorba_Hi_base_epv = {
NULL,             /* _private data */
(gpointer) & impl_HiCorba_Hi__destroy, /* finalize routine */
NULL,             /* default_POA routine */
};
#endif

#if !defined(_impl_HiCorba_Hi_epv_)
#define _impl_HiCorba_Hi_epv_ 1
static POA_HiCorba_Hi__epv impl_HiCorba_Hi_epv = {
NULL, /* _private */
(gpointer)&impl_HiCorba_Hi_sayHiTo,
(gpointer)&impl_HiCorba_Hi_add,
(gpointer)&impl_HiCorba_Hi_shutdown,
};
#endif


/*** vepv structures ***/

#if !defined(_impl_HiCorba_Hi_vepv_)
#define _impl_HiCorba_Hi_vepv_ 1
static POA_HiCorba_Hi__vepv impl_HiCorba_Hi_vepv = {
&impl_HiCorba_Hi_base_epv,
&impl_HiCorba_Hi_epv,
};
#endif


/*** Stub implementations ***/

#if !defined(_impl_HiCorba_Hi__create_)
#define _impl_HiCorba_Hi__create_ 1
static HiCorba_Hi impl_HiCorba_Hi__create(PortableServer_POA poa, CORBA_Environment *ev)
{
HiCorba_Hi retval;
impl_POA_HiCorba_Hi *newservant;
PortableServer_ObjectId *objid;

newservant = g_new0(impl_POA_HiCorba_Hi, 1);
newservant->servant.vepv = &impl_HiCorba_Hi_vepv;
newservant->poa = (PortableServer_POA) CORBA_Object_duplicate((CORBA_Object)poa, ev);
POA_HiCorba_Hi__init((PortableServer_Servant)newservant, ev);
   /* Before servant is going to be activated all
    * private attributes must be initialized.  */

   /* ------ init private attributes here ------ */
   /* ------ ---------- end ------------- ------ */

objid = PortableServer_POA_activate_object(poa, newservant, ev);
CORBA_free(objid);
retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);

return retval;
}
#endif

#if !defined(_impl_HiCorba_Hi__destroy_)
#define _impl_HiCorba_Hi__destroy_ 1
static void
impl_HiCorba_Hi__destroy(impl_POA_HiCorba_Hi *servant, CORBA_Environment *ev)
{
    CORBA_Object_release ((CORBA_Object) servant->poa, ev);

    /* No further remote method calls are delegated to 
    * servant and you may free your private attributes. */
   /* ------ free private attributes here ------ */
   /* ------ ---------- end ------------- ------ */

POA_HiCorba_Hi__fini((PortableServer_Servant)servant, ev);

g_free (servant);
}
#endif

#if !defined(_impl_HiCorba_Hi_sayHiTo_)
#define _impl_HiCorba_Hi_sayHiTo_ 1
static CORBA_string
impl_HiCorba_Hi_sayHiTo(impl_POA_HiCorba_Hi *servant,
const CORBA_char * someone,
CORBA_Environment *ev)
{
 CORBA_string retval = CORBA_string_alloc(512);
 /* ------   insert method code here   ------ */
 sprintf(retval,"Hi, %s !",someone);
 g_print("\nServer>server is returning: %s",retval);

 /* ------ ---------- end ------------ ------ */

 return retval;
}
#endif

#if !defined(_impl_HiCorba_Hi_add_)
#define _impl_HiCorba_Hi_add_ 1
static CORBA_long
impl_HiCorba_Hi_add(impl_POA_HiCorba_Hi *servant,
const CORBA_long numa,
const CORBA_long numb,
CORBA_Environment *ev)
{
 CORBA_long retval;
 /* ------   insert method code here   ------ */
 retval = numa+numb;
 /* ------ ---------- end ------------ ------ */

 return retval;
}
#endif

#if !defined(_impl_HiCorba_Hi_shutdown_)
#define _impl_HiCorba_Hi_shutdown_ 1
static CORBA_ORB _neo_ORB = CORBA_OBJECT_NIL;
static HiCorba_Hi _neo_servant =  CORBA_OBJECT_NIL;
static void set_NEO_ORB(CORBA_ORB theORB, HiCorba_Hi theServant)
{
	_neo_ORB = theORB;
	_neo_servant = theServant;
}

static void
impl_HiCorba_Hi_shutdown(impl_POA_HiCorba_Hi *servant,
CORBA_Environment *ev)
{
 /* ------   insert method code here   ------ */
 if(_neo_ORB==CORBA_OBJECT_NIL || _neo_servant ==  CORBA_OBJECT_NIL)return;
 //
 g_print("\nServer>executing the release");
 CORBA_Object_release(_neo_servant,ev);
 if((ev)->_major != CORBA_NO_EXCEPTION){
   g_error ("%s %s", "Object_release failed", CORBA_exception_id (ev));
   CORBA_exception_free (ev);
   abort();
 }
 //
 g_print("\nServer>executing the shutdown");
 CORBA_ORB_shutdown(_neo_ORB, CORBA_FALSE, ev);
 if((ev)->_major != CORBA_NO_EXCEPTION){
   g_error ("%s %s", "shutdown failed", CORBA_exception_id (ev));
   CORBA_exception_free (ev);
   abort();
 }
 exit(0);
 /* ------ ---------- end ------------ ------ */
}
#endif

MakeServer

CC       = gcc
CFLAGS   = -c -g -pthread -D_REENTRANT -DORBIT2=1 \
           -I/usr/include/orbit-2.0 \
           -I/usr/include/glib-2.0 \
           -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
LDFLAGS  = -Wl,--export-dynamic -lORBit-2 -lORBitCosNaming-2 -lgmodule-2.0 \
           -ldl -lgobject-2.0 -lgthread-2.0 -lpthread -lglib-2.0 -lm \
           -L/usr/lib
ORBIT_IDL= /usr/bin/orbit-idl-2

all : Hi-server-ior.bin

Hi-server-ior.bin : Hi-common.o Hi-skelimpl.o Hi-skels.o Hi-server-ior.o
	$(CC) $(LDFLAGS) Hi-common.o Hi-skelimpl.o Hi-skels.o Hi-server-ior.o -o Hi-server-ior.bin

%.o : %.c 
	$(CC) $(CFLAGS) $< -o $@ 

nidl : Hi.idl
	$(ORBIT_IDL) Hi.idl
	$(ORBIT_IDL) --skeleton-impl Hi.idl

clean:
	rm -rf *.bin
	rm -rf *.o

编译

make -f MakeServer

CPP实现CORBA静态绑定(六)

  • CORBA基本架构
  • IDL文件编写
  • CPP示例实现(上)
  • CPP示例实现(下)
  • C示例实现(IOR+NS上)
  • C示例实现(IOR+NS下)
  • C示例实现(IOR上)
  • C示例实现(IOR下)

首先完成客户端部分:
Hi-client-ns.c

#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <orbit/orbit.h>
#include <ORBitservices/CosNaming.h>
#include <ORBitservices/CosNaming_impl.h>

#include "Hi.h"

/*
Usage: ./hi-client_ns
*/

/**
 * test for exception
 */
static
gboolean
raised_exception(CORBA_Environment *ev)
{
	return ((ev)->_major != CORBA_NO_EXCEPTION);
}

/**
 * in case of any exception this macro will abort the process
 */
static
void
abort_if_exception(CORBA_Environment *ev, const char* mesg)
{
	if (raised_exception (ev)) {
		g_error ("%s %s", mesg, CORBA_exception_id (ev));
		CORBA_exception_free (ev);
		abort();
	}
}


/*
 * main
 */
int main(int argc, char* argv[])
{
	CORBA_ORB orb=CORBA_OBJECT_NIL;
	CORBA_Environment ev;
	CosNaming_NamingContext ns =CORBA_OBJECT_NIL;
	HiCorba_Hi service = CORBA_OBJECT_NIL;
	CORBA_char  name_service[]="Hi";
	CosNaming_NameComponent path[1]={name_service,""};
	CosNaming_Name name={1,1,path,CORBA_FALSE};

	//init orb
	g_print("\nClient>starting client...");
	g_print("\nClient>creating and initializing the ORB");
	CORBA_exception_init(&ev);
	abort_if_exception(&ev, "CORBA_exception_init failed");
	orb=CORBA_ORB_init(&argc,argv,"orbit-local-orb",&ev);
	abort_if_exception(&ev, "CORBA_ORB_init failed");

	// read name_service ior from ns.ior 
	CORBA_char  filename[] = "ns.ior";
 	FILE *file   = NULL;
	g_print("\nClient>reading the file '%s'",filename);
	if ((file=fopen(filename, "r"))==NULL)
                g_error ("could not open '%s'", filename);
	gchar objref[1024];
	fscanf (file, "%s", &objref);
	g_print("\nClient>getting the root naming context 'NameService' - from the file '%s'",filename);
	g_print("\nClient>the root naming context ior is '%s'",objref);
        ns = (CosNaming_NamingContext)CORBA_ORB_string_to_object(orb,objref,&ev);
	//free (objref);
	abort_if_exception(&ev, "CORBA_ORB_string_to_object 'NameService IOR' failed");

        //resolve object reference
	g_print("\nClient>Resolving the object reference in naming '%s'",name_service);
	service=CosNaming_NamingContext_resolve(ns,&name,&ev);
	abort_if_exception(&ev, "resolve failed");

	// invoke service
	g_print("\nClient>calling the Hi service...");
	CORBA_char *msg=HiCorba_Hi_sayHiTo(service, "neohope", &ev);
	abort_if_exception(&ev, "HiCorba_Hi_sayHiTo failed");
        g_print("\nClient>server returned the following message: %s\n", msg);

	CORBA_Object_release(service, &ev);
	abort_if_exception(&ev, "release failed");

        if (orb != CORBA_OBJECT_NIL)
        {
           /* going to destroy orb.. */
           CORBA_ORB_destroy(orb, &ev);
	   abort_if_exception(&ev, "destroy failed");
	}

}

MakeClient

CC       = gcc
CFLAGS   = -c -g -pthread -D_REENTRANT -DORBIT2=1 \
           -I/usr/include/orbit-2.0 \
           -I/usr/include/glib-2.0 \
           -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
LDFLAGS  = -Wl,--export-dynamic -lORBit-2 -lORBitCosNaming-2 -lgmodule-2.0 \
           -ldl -lgobject-2.0 -lgthread-2.0 -lpthread -lglib-2.0 -lm \
           -L/usr/lib
ORBIT_IDL= /usr/bin/orbit-idl-2

all : Hi-client-ns.bin

Hi-client-ns.bin : Hi-common.o Hi-stubs.o Hi-client-ns.o
	$(CC) $(LDFLAGS) Hi-common.o Hi-stubs.o Hi-client-ns.o -o Hi-client-ns.bin

%.o : %.c 
	$(CC) $(CFLAGS) $< -o $@ 

nidl : Hi.idl
	$(ORBIT_IDL) Hi.idl
	$(ORBIT_IDL) --skeleton-impl Hi.idl

clean:
	rm -rf *.bin
	rm -rf *.o

编译

make -f MakeClient

然后是运行

#首先运行orbd
orbd -ORBInitialPort 1900

#然后运行nameservice
orbit-name-server-2 > ns.ior

#然后运行server
./Hi-server-ns.bin
Server>starting server...
Server>creating and initializing the ORB
Server>getting reference to RootPOA
Server>activating the POA Manager
Server>creating the servant
Server>reading the file 'ns.ior'
Server>getting the root naming context 'NameService' - from the file 'ns.ior'
Server>the root naming context ior is 'IOR:010000002b00000049444c3a6f6d672e6f72672f436f734e616d696e672f4e616d696e67436f6e746578744578743a312e300000030000000054424f580000000101020005000000554e4958000000000a0000006c6f63616c686f73740000002d0000002f746d702f6f726269742d6e656f686f70652f6c696e632d313735302d302d346431323731616531616661390000000000000000caaedfba58000000010102002d0000002f746d702f6f726269742d6e656f686f70652f6c696e632d313735302d302d34643132373161653161666139000000001c00000000000000d4d2dcc0a89f68a8c02b28282828282801000000eaaf213d01000000480000000100000002000000050000001c00000000000000d4d2dcc0a89f68a8c02b28282828282801000000eaaf213d01000000140000000100000001000105000000000901010000000000'
Server>binding the object reference in naming with name 'Hi'
Server>running the orb...
Server>server is returning: Hi, neohope !

#然后运行client
./Hi-client-ns.bin
Client>starting client...
Client>creating and initializing the ORB
Client>reading the file 'ns.ior'
Client>getting the root naming context 'NameService' - from the file 'ns.ior'
Client>the root naming context ior is 'IOR:010000002b00000049444c3a6f6d672e6f72672f436f734e616d696e672f4e616d696e67436f6e746578744578743a312e300000030000000054424f580000000101020005000000554e4958000000000a0000006c6f63616c686f73740000002d0000002f746d702f6f726269742d6e656f686f70652f6c696e632d313735302d302d346431323731616531616661390000000000000000caaedfba58000000010102002d0000002f746d702f6f726269742d6e656f686f70652f6c696e632d313735302d302d34643132373161653161666139000000001c00000000000000d4d2dcc0a89f68a8c02b28282828282801000000eaaf213d01000000480000000100000002000000050000001c00000000000000d4d2dcc0a89f68a8c02b28282828282801000000eaaf213d01000000140000000100000001000105000000000901010000000000'
Client>Resolving the object reference in naming 'Hi'
Client>calling the Hi service...
Client>server returned the following message: Hi, neohope !

CPP实现CORBA静态绑定(五)

  • CORBA基本架构
  • IDL文件编写
  • CPP示例实现(上)
  • CPP示例实现(下)
  • C示例实现(IOR+NS上)
  • C示例实现(IOR+NS下)
  • C示例实现(IOR上)
  • C示例实现(IOR下)

在linux系统下,有很多开源的CORBA通讯框架,在C的示例中,使用了orbit的框架。
如我用的是Debian系统,可以直接安装:

apt-get install orbit2
apt-get install orbit2-nameserver
apt-get install liborbit2-dev

安装后,可以通过工具orb-rdl-2从idl文件生成需要的stubs及skeletons接口代码:

#该命令会生成文件:Hi.h、Hi-common.c、Hi-skels.c、Hi-stubs.c
orbit-idl-2 Hi.idl

可以通过工具orb-rdl-2从idl文件生成服务端代码:

#该命令会生成模板文件:Hi-skelimpl.c
orbit-idl-2 --skeleton-impl Hi.idl

首先完成服务端部分:
Hi-server-ns.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <orbit/orbit.h>
#include <ORBitservices/CosNaming.h>
#include <ORBitservices/CosNaming_impl.h>
#include "Hi.h"
#include "Hi-skelimpl.c"
/*
./Hi-server_ns
*/

/**
 * test for exception 
*/
static
gboolean
raised_exception(CORBA_Environment *ev) {
	return ((ev)->_major != CORBA_NO_EXCEPTION);
}

/**
 * in case of any exception this macro will abort the process
*/
static
void
abort_if_exception(CORBA_Environment *ev, const char* mesg)
{
	if (raised_exception (ev)) {
		g_error ("%s %s", mesg, CORBA_exception_id (ev));
		CORBA_exception_free (ev);
		abort();
	}
}

/*
 * main
*/
int
main (int argc, char *argv[])
{
	PortableServer_POA poa;
	HiCorba_Hi servant = CORBA_OBJECT_NIL;
	CosNaming_NamingContext ns =CORBA_OBJECT_NIL;
	CORBA_ORB orb=CORBA_OBJECT_NIL;
	CORBA_char name_service[]="Hi";
	CosNaming_NameComponent path[1]={name_service,""};
	CosNaming_Name name={1,1,path,CORBA_FALSE};
	CORBA_Environment ev;

	// init ORB
	g_print("\nServer>starting server...");
	g_print("\nServer>creating and initializing the ORB");
	CORBA_exception_init(&ev);
	abort_if_exception(&ev, "CORBA_exception_init failed");
	orb=CORBA_ORB_init(&argc,argv,"orbit-local-orb",&ev);
	abort_if_exception(&ev, "CORBA_ORB_init failed");

	// activate POA
	g_print("\nServer>getting reference to RootPOA");
	poa= (PortableServer_POA) CORBA_ORB_resolve_initial_references(orb,"RootPOA",&ev);
	abort_if_exception(&ev, "CORBA_ORB_resolve_initial 'RootPOA' failed");
	g_print("\nServer>activating the POA Manager");
	PortableServer_POAManager_activate(PortableServer_POA__get_the_POAManager(poa, &ev),&ev);
	abort_if_exception(&ev, "POA_activate failed");

	// create servant
	g_print("\nServer>creating the servant");
	servant = impl_HiCorba_Hi__create (poa, &ev);
	abort_if_exception(&ev, "impl_HiCorba_Hi__create failed");
	
	// read name_service ior from ns.ior 
	CORBA_char  filename[] = "ns.ior";
 	FILE *file   = NULL;
	g_print("\nServer>reading the file '%s'",filename);
	if ((file=fopen(filename, "r"))==NULL)
                g_error ("could not open '%s'\n", filename);
	gchar objref[1024];
	fscanf (file, "%s", &objref);
	g_print("\nServer>getting the root naming context 'NameService' - from the file '%s'",filename);
	g_print("\nServer>the root naming context ior is '%s'",objref);

	// bind service 
	ns = (CosNaming_NamingContext) CORBA_ORB_string_to_object (orb, objref, &ev);
	//free (objref);
	abort_if_exception(&ev, "CORBA_ORB_string_to_object 'NameService IOR' failed");
	g_print("\nServer>binding the object reference in naming with name '%s'",name_service);
	CosNaming_NamingContext_rebind(ns,&name,servant,&ev);
	abort_if_exception(&ev, "rebind failed");
	
	// start 
	g_print("\nServer>running the orb...");
	CORBA_ORB_run(orb,&ev);
	abort_if_exception(&ev, "ORB_run failed");
}

Hi-skelimpl.c

/* This is a template file generated by command */
/* orbit-idl-2 --skeleton-impl Hi.idl */
/* User must edit this file, inserting servant  */
/* specific code between markers. */

#include <stdlib.h>
#include <stdio.h>
#include "Hi.h"

/*** App-specific servant structures ***/

#if !defined(_typedef_impl_POA_HiCorba_Hi_)
#define _typedef_impl_POA_HiCorba_Hi_ 1
typedef struct {
POA_HiCorba_Hi servant;
PortableServer_POA poa;
   /* ------ add private attributes here ------ */
   /* ------ ---------- end ------------ ------ */
} impl_POA_HiCorba_Hi;
#endif

/*** Implementation stub prototypes ***/

#if !defined(_decl_impl_HiCorba_Hi__destroy_)
#define _decl_impl_HiCorba_Hi__destroy_ 1
static void impl_HiCorba_Hi__destroy(impl_POA_HiCorba_Hi *servant,
CORBA_Environment *ev);
#endif

#if !defined(_decl_impl_HiCorba_Hi_sayHiTo_)
#define _decl_impl_HiCorba_Hi_sayHiTo_ 1
static CORBA_string
impl_HiCorba_Hi_sayHiTo(impl_POA_HiCorba_Hi *servant,
const CORBA_char * someone,
CORBA_Environment *ev);
#endif

#if !defined(_decl_impl_HiCorba_Hi_add_)
#define _decl_impl_HiCorba_Hi_add_ 1
static CORBA_long
impl_HiCorba_Hi_add(impl_POA_HiCorba_Hi *servant,
const CORBA_long numa,
const CORBA_long numb,
CORBA_Environment *ev);
#endif

#if !defined(_decl_impl_HiCorba_Hi_shutdown_)
#define _decl_impl_HiCorba_Hi_shutdown_ 1


static void
impl_HiCorba_Hi_shutdown(impl_POA_HiCorba_Hi *servant,
CORBA_Environment *ev);
#endif


/*** epv structures ***/

#if !defined(_impl_HiCorba_Hi_base_epv_)
#define _impl_HiCorba_Hi_base_epv_ 1
static PortableServer_ServantBase__epv impl_HiCorba_Hi_base_epv = {
NULL,             /* _private data */
(gpointer) & impl_HiCorba_Hi__destroy, /* finalize routine */
NULL,             /* default_POA routine */
};
#endif

#if !defined(_impl_HiCorba_Hi_epv_)
#define _impl_HiCorba_Hi_epv_ 1
static POA_HiCorba_Hi__epv impl_HiCorba_Hi_epv = {
NULL, /* _private */
(gpointer)&impl_HiCorba_Hi_sayHiTo,
(gpointer)&impl_HiCorba_Hi_add,
(gpointer)&impl_HiCorba_Hi_shutdown,
};
#endif


/*** vepv structures ***/

#if !defined(_impl_HiCorba_Hi_vepv_)
#define _impl_HiCorba_Hi_vepv_ 1
static POA_HiCorba_Hi__vepv impl_HiCorba_Hi_vepv = {
&impl_HiCorba_Hi_base_epv,
&impl_HiCorba_Hi_epv,
};
#endif


/*** Stub implementations ***/

#if !defined(_impl_HiCorba_Hi__create_)
#define _impl_HiCorba_Hi__create_ 1
static HiCorba_Hi impl_HiCorba_Hi__create(PortableServer_POA poa, CORBA_Environment *ev)
{
HiCorba_Hi retval;
impl_POA_HiCorba_Hi *newservant;
PortableServer_ObjectId *objid;

newservant = g_new0(impl_POA_HiCorba_Hi, 1);
newservant->servant.vepv = &impl_HiCorba_Hi_vepv;
newservant->poa = (PortableServer_POA) CORBA_Object_duplicate((CORBA_Object)poa, ev);
POA_HiCorba_Hi__init((PortableServer_Servant)newservant, ev);
   /* Before servant is going to be activated all
    * private attributes must be initialized.  */

   /* ------ init private attributes here ------ */
   /* ------ ---------- end ------------- ------ */

objid = PortableServer_POA_activate_object(poa, newservant, ev);
CORBA_free(objid);
retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);

return retval;
}
#endif

#if !defined(_impl_HiCorba_Hi__destroy_)
#define _impl_HiCorba_Hi__destroy_ 1
static void
impl_HiCorba_Hi__destroy(impl_POA_HiCorba_Hi *servant, CORBA_Environment *ev)
{
    CORBA_Object_release ((CORBA_Object) servant->poa, ev);

    /* No further remote method calls are delegated to 
    * servant and you may free your private attributes. */
   /* ------ free private attributes here ------ */
   /* ------ ---------- end ------------- ------ */

POA_HiCorba_Hi__fini((PortableServer_Servant)servant, ev);

g_free (servant);
}
#endif

#if !defined(_impl_HiCorba_Hi_sayHiTo_)
#define _impl_HiCorba_Hi_sayHiTo_ 1
static CORBA_string
impl_HiCorba_Hi_sayHiTo(impl_POA_HiCorba_Hi *servant,
const CORBA_char * someone,
CORBA_Environment *ev)
{
 CORBA_string retval = CORBA_string_alloc(512);
 /* ------   insert method code here   ------ */
 sprintf(retval,"Hi, %s !",someone);
 g_print("\nServer>server is returning: %s",retval);

 /* ------ ---------- end ------------ ------ */

 return retval;
}
#endif

#if !defined(_impl_HiCorba_Hi_add_)
#define _impl_HiCorba_Hi_add_ 1
static CORBA_long
impl_HiCorba_Hi_add(impl_POA_HiCorba_Hi *servant,
const CORBA_long numa,
const CORBA_long numb,
CORBA_Environment *ev)
{
 CORBA_long retval;
 /* ------   insert method code here   ------ */
 retval = numa+numb;
 /* ------ ---------- end ------------ ------ */

 return retval;
}
#endif

#if !defined(_impl_HiCorba_Hi_shutdown_)
#define _impl_HiCorba_Hi_shutdown_ 1
static CORBA_ORB _neo_ORB = CORBA_OBJECT_NIL;
static HiCorba_Hi _neo_servant =  CORBA_OBJECT_NIL;
static void set_NEO_ORB(CORBA_ORB theORB, HiCorba_Hi theServant)
{
	_neo_ORB = theORB;
	_neo_servant = theServant;
}

static void
impl_HiCorba_Hi_shutdown(impl_POA_HiCorba_Hi *servant,
CORBA_Environment *ev)
{
 /* ------   insert method code here   ------ */
 if(_neo_ORB==CORBA_OBJECT_NIL || _neo_servant ==  CORBA_OBJECT_NIL)return;
 //
 g_print("\nServer>executing the release");
 CORBA_Object_release(_neo_servant,ev);
 if((ev)->_major != CORBA_NO_EXCEPTION){
   g_error ("%s %s", "Object_release failed", CORBA_exception_id (ev));
   CORBA_exception_free (ev);
   abort();
 }
 //
 g_print("\nServer>executing the shutdown");
 CORBA_ORB_shutdown(_neo_ORB, CORBA_FALSE, ev);
 if((ev)->_major != CORBA_NO_EXCEPTION){
   g_error ("%s %s", "shutdown failed", CORBA_exception_id (ev));
   CORBA_exception_free (ev);
   abort();
 }
 exit(0);
 /* ------ ---------- end ------------ ------ */
}
#endif

MakeServer

CC       = gcc
CFLAGS   = -c -g -pthread -D_REENTRANT -DORBIT2=1 \
           -I/usr/include/orbit-2.0 \
           -I/usr/include/glib-2.0 \
           -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
LDFLAGS  = -Wl,--export-dynamic -lORBit-2 -lORBitCosNaming-2 -lgmodule-2.0 \
           -ldl -lgobject-2.0 -lgthread-2.0 -lpthread -lglib-2.0 -lm \
           -L/usr/lib
ORBIT_IDL= /usr/bin/orbit-idl-2

all : Hi-server-ns.bin

Hi-server-ns.bin : Hi-common.o Hi-skelimpl.o Hi-skels.o Hi-server-ns.o
	$(CC) $(LDFLAGS) Hi-common.o Hi-skelimpl.o Hi-skels.o Hi-server-ns.o -o Hi-server-ns.bin

%.o : %.c 
	$(CC) $(CFLAGS) $< -o $@ 

nidl : Hi.idl
	$(ORBIT_IDL) Hi.idl
	$(ORBIT_IDL) --skeleton-impl Hi.idl

clean:
	rm -rf *.bin
	rm -rf *.o

编译

make -f MakeServer

CPP实现CORBA静态绑定(四)

  • CORBA基本架构
  • IDL文件编写
  • CPP示例实现(上)
  • CPP示例实现(下)
  • C示例实现(IOR+NS上)
  • C示例实现(IOR+NS下)
  • C示例实现(IOR上)
  • C示例实现(IOR下)

然后完成客户端部分,同样分了三个文件:

HiClientImpl.hh

#include <iostream>
#include <fstream>
#include "Hi.hh"
                                                                                
using namespace std;
                                                                                
class HiClientImpl {
public:
   HiClientImpl();
   ~HiClientImpl();
   void TestAdd();
                                                                                
   CosNaming::Name m_corbaCosName;
                                                                                
   // CORBA ORB
   CORBA::ORB_var             m_orb;
   // ORB Object                                                                     
   CORBA::Object_var          m_obj;   
   // Resolved id to object reference   
   CORBA::Object_var          m_obj1;                                                                                  
   // Resolved and narrowed CORBA object for proxy calls
   HiCorba::Hi_var            m_Data;
};
                                                                                
class DS_ServerConnectionException{
public:
   DS_ServerConnectionException() { cerr << "CORBA COMM_FAILURE" << endl; };
};
                                                                                
class DS_SystemException{
public:
   DS_SystemException() { cerr << "CORBA Exception" << endl; };
};
                                                                                
class DS_FatalException{
public:
   DS_FatalException() { cerr << "CORBA Fatal Exception" << endl; };
};
                                                                                
class DS_Exception{
public:
   DS_Exception() { cerr << "Exception" << endl; };
};

HiClientImpl.cc

#include "assert.h"
#include "HiClientImpl.hh"
#include "Hi.hh"
                                                                                
HiClientImpl::HiClientImpl()
{
  try {
    //------------------------------------------------------------------------
    // Initialize ORB object.
    //------------------------------------------------------------------------
    int    argc=0;       // Dummy variables to support following call.
    char** argv=0;
    CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

    //------------------------------------------------------------------------
    // Bind ORB object to name service object.
    // (Reference to Name service root context.)
    //------------------------------------------------------------------------
    //CORBA::Object_var obj = orb->resolve_initial_references("OmniNameService");
    CORBA::Object_var obj = orb->resolve_initial_references("NameService");
    assert (!CORBA::is_nil(obj.in()));
    cerr << "resolve_initial_reference OK" << endl;
                                                                                
    //------------------------------------------------------------------------
    // Narrow this to the naming context (Narrowed reference to root context.)
    //------------------------------------------------------------------------
    CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow(obj.in());
    assert (!CORBA::is_nil(nc.in()));
    cerr << "narrow ok" << endl;
                                                                                
    //------------------------------------------------------------------------
    // The "name text" put forth by CORBA server in name service.
    // This same name ("DataServiceName1") is used by the CORBA server when
    // binding to the name server (CosNaming::Name).
    //------------------------------------------------------------------------
    CosNaming::Name _corbaCosName;
    _corbaCosName.length(1);
    _corbaCosName[0].id=CORBA::string_dup("Hi");
                                                                                
    //------------------------------------------------------------------------
    // Resolve "name text" identifier to an object reference.
    //------------------------------------------------------------------------
    CORBA::Object_var obj1 = nc->resolve(_corbaCosName);
    assert(!CORBA::is_nil(obj1.in()));
    cerr << "resolve OK" << endl;
                                                                                
    m_Data = HiCorba::Hi::_narrow(obj1.in());
    if (CORBA::is_nil(m_Data.in()))
    {
       cerr << "IOR is not an SA object reference." << endl;
    }
    else{
        cerr << "narrow OK" << endl;
    }
  }
  catch(CORBA::COMM_FAILURE& ex) {
    cerr << "Caught system exception COMM_FAILURE -- unable to contact the "
         << "object." << endl;
    throw DS_ServerConnectionException();
    return;
  }
  catch(CORBA::SystemException& ) {
    cerr << "Caught a CORBA::SystemException." << endl;
    throw DS_SystemException();
    return;
  }
  catch(CORBA::Exception& ) {
    cerr << "Caught CORBA::Exception." << endl;
    throw DS_Exception();
    return;
  }  catch(omniORB::fatalException& fe) {
    cerr << "Caught omniORB::fatalException:" << endl;
    cerr << "  file: " << fe.file() << endl;
    cerr << "  line: " << fe.line() << endl;
    cerr << "  mesg: " << fe.errmsg() << endl;
    throw DS_FatalException();
    return;
  }
  catch(...) {
    cerr << "Caught unknown exception." << endl;
    throw DS_Exception();
    return;
  }
  return;
}
                                                                                
HiClientImpl::~HiClientImpl()
{
}
                                                                                
void HiClientImpl::TestAdd()
{
   CORBA::Long num1=70;
   CORBA::Long num2=80;
   CORBA::Long retNum;
                                                                                
   cout << "Values input to Server: "
        << num1 << " "
        << num2 << " " << endl;
                                                                                
   if( retNum = m_Data->add( num1, num2)) // This is the CORBA call which is to be executed remotely
   {    // Ok
      cout << "Values returned by Server: "
           << num1 << "+"
           << num2 << "="
           << retNum << endl;
   }
}

HiClient.cc

#include "HiClientImpl.hh"
                                                                                
int main(int argc, char** argv)
{
   HiClientImpl impl;  
   impl.TestAdd();                                                      
   return 0;
}

MakeClient

CC            = /usr/bin/g++
CPPFLAGS      = -g -c -I/usr/include -I/usr/include/omniORB4
LDFLAGS       = -g -L/usr/lib -lomniORB4 -lomnithread -lomniDynamic4
OMNIIDL       = /usr/bin/omniidl
                                                                                
all: HiClient.bin

HiClient.bin: HiClient.o HiClientImpl.o HiSK.o
	$(CC) $(LDFLAGS) -o HiClient.bin HiClient.o HiClientImpl.o HiSK.o
                                                                                
HiSK.o: HiSK.cc Hi.hh
	$(CC) $(CPPFLAGS) $(INCLUDES) HiSK.cc
                                                                                
HiClient.o: HiClient.cc HiClientImpl.hh
	$(CC) $(CPPFLAGS) HiClient.cc
                                                                                
HiClientImpl.o: HiClientImpl.cc HiClientImpl.hh Hi.hh
	$(CC) $(CPPFLAGS) HiClientImpl.cc
                                                                                
nidl: Hi.idl
	$(OMNIIDL) -bcxx Hi.idl
                                                                                
clean:
	rm -f *.o

编译

make -f MakeClient

然后是运行

#首先检查OMNI Naming Service是否在运行,默认端口2809
ps -aux | grep omni
root      1585  0.0  0.2 315608  4912 ?        Sl   12:04   0:00 /usr/bin/omniNames -errlog /var/log/omniorb-nameserver.log
neohope   1943  0.0  0.1  12720  2180 tty2     S+   14:57   0:00 grep omni

#运行服务端
./HiServer

#运行客户端
./HiClient
>>Values input to Server: 70 80
>>Values returned by Server: 70+80=150

CPP实现CORBA静态绑定(三)

  • CORBA基本架构
  • IDL文件编写
  • CPP示例实现(上)
  • CPP示例实现(下)
  • C示例实现(IOR+NS上)
  • C示例实现(IOR+NS下)
  • C示例实现(IOR上)
  • C示例实现(IOR下)

在linux系统下,有很多开源的CORBA通讯框架,在CPP的示例中,使用了OmniORB的框架。
如我用的是Debian系统,可以直接安装:

apt-get install omniorb
apt-get install omniorb-nameserver
apt-get install omniidl
apt-get install libomniorb4-dev
export OMNIORB_CONFIG=/etc/omniORB.cfg

然后修改配置文件/etc/omniORB.cfg,修改日志输出级别。

编译Hi.idl文件,将生成文件Hi.hh及HiSK.cc

omniidl -bcxx Hi.idl

首先完成服务端部分,分了三个文件:

HiServerImpl.hh

#include <CORBA.h>
#include "Hi.hh"

class HiServerImpl : public virtual POA_HiCorba::Hi, public virtual PortableServer::RefCountServantBase
{
	public:
		HiServerImpl();
		~HiServerImpl();
		char* sayHiTo(const char* someone);
		::CORBA::Long add(::CORBA::Long numa, ::CORBA::Long numb);
		void shutdown();
};

HiServerImpl.cc

#include <vector>
#include <string>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <sys/wait.h>

#include "HiServerImpl.hh"

using namespace HiCorba;

HiServerImpl::HiServerImpl()
{
}

HiServerImpl::~HiServerImpl()
{
}

char* HiServerImpl::sayHiTo(const char* someone)
{

}

::CORBA::Long HiServerImpl::add(::CORBA::Long numa, ::CORBA::Long numb)
{
	return numa+numb;
}

void HiServerImpl::shutdown()
{

}

HiServer.cc

#include <stdlib.h>
#include <iostream>
#include <string>
#include <assert.h>
#include <signal.h>
#include <unistd.h>

#include "HiServerImpl.hh"
#include "Hi.hh"

using namespace std;

int main(int argc, char** argv)
{
	try {
		//------------------------------------------------------------------------
		// Initialize CORBA ORB - "orb"
		//------------------------------------------------------------------------
		CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

		//------------------------------------------------------------------------
		// Servant must register with POA in order to be made available for client
		// Get reference to the RootPOA.
		//------------------------------------------------------------------------
		CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
		PortableServer::POA_var _poa = PortableServer::POA::_narrow(obj.in());

		//------------------------------------------------------------------------
		// Operations defined in object interface invoked via an object reference.
		// Instance of CRequestSocketStream_i servant is initialized.
		//------------------------------------------------------------------------
		HiServerImpl* impl = new HiServerImpl();

		//------------------------------------------------------------------------
		// Servant object activated in RootPOA.
		// (Object id used for various POA operations.)
		//------------------------------------------------------------------------
		PortableServer::ObjectId_var myOid = _poa->activate_object(impl);

		//------------------------------------------------------------------------
		// Obtain object reference from servant and register in naming service(??)
		//------------------------------------------------------------------------
		CORBA::Object_var SA_obj = impl->_this();

		//------------------------------------------------------------------------
		// Obtain a reference to the object, and print it out as string IOR.
		//------------------------------------------------------------------------
		CORBA::String_var sior(orb->object_to_string(SA_obj.in()));
		cerr << "'" << (char*)sior << "'" << endl;

		//========================================================================
		// Bind (rebind) object (orb) to name (SA_obj)
		//========================================================================

		//------------------------------------------------------------------------
		// Bind object to name service as defined by directive InitRef
		// and identifier "OmniNameService" in config file omniORB.cfg.
		//------------------------------------------------------------------------
		//CORBA::Object_var obj1=orb->resolve_initial_references("OmniNameService");
		CORBA::Object_var obj1=orb->resolve_initial_references("NameService");
		assert(!CORBA::is_nil(obj1.in()));
		cerr << "resolve_initial_references successed" << endl;

		//------------------------------------------------------------------------
		// narrow this to the naming context
		//------------------------------------------------------------------------
		CosNaming::NamingContext_var nc = CosNaming::NamingContext::_narrow(obj1.in());
		assert(!CORBA::is_nil(nc.in()));
		cerr << "narrow successed" << endl;

		//------------------------------------------------------------------------
		// Bind to CORBA name service. Same name to be requested by client.
		//------------------------------------------------------------------------
		CosNaming::Name name;
		name.length(1);
		name[0].id=CORBA::string_dup("Hi");
		nc->rebind (name,SA_obj.in());
		cerr << "rebind successed" << endl;

		//========================================================================
		impl->_remove_ref();

		//------------------------------------------------------------------------
		// Activate the POA manager
		//------------------------------------------------------------------------
		PortableServer::POAManager_var pmgr = _poa->the_POAManager();
		pmgr->activate();
		cerr << "poamanager activate successed" << endl;

		//------------------------------------------------------------------------
		// Accept requests from clients
		//------------------------------------------------------------------------
		orb->run();

		//------------------------------------------------------------------------
		// If orb leaves event handling loop.
		// - currently configured never to time out (??)
		//------------------------------------------------------------------------
		orb->destroy();

		free(name[0].id); // str_dup does a malloc internally
	}
	catch(CORBA::SystemException&) {
		cerr << "Caught CORBA::SystemException." << endl;
	}
	catch(CORBA::Exception&) {
		cerr << "Caught CORBA::Exception." << endl;
	}
	catch(omniORB::fatalException& fe) {
		cerr << "Caught omniORB::fatalException:" << endl;
		cerr << "  file: " << fe.file() << endl;
		cerr << "  line: " << fe.line() << endl;
		cerr << "  mesg: " << fe.errmsg() << endl;
	}
	catch(...) {
		cerr << "Caught unknown exception." << endl;
	}

	return 0;
}

MakeServer

CC            = /usr/bin/g++
CPPFLAGS      = -g -c -I/usr/include -I/usr/include/omniORB4
LDFLAGS       = -g -L/usr/lib -lomniORB4 -lomnithread -lomniDynamic4
OMNIIDL       = /usr/bin/omniidl

all: HiServer.bin
                                                            
HiServer.bin:  HiSK.o HiServerImpl.o HiServer.o
	$(CC) $(LDFLAGS) -o HiServer.bin HiSK.o HiServerImpl.o HiServer.o
                                                                                
HiSK.o: HiSK.cc Hi.hh
	$(CC) $(CPPFLAGS) $(INCLUDES) HiSK.cc
                                                                                
HiServer.o: HiServer.cc Hi.hh
	$(CC) $(CPPFLAGS) $(INCLUDES) HiServer.cc
                                                                                
HiServerImpl_i.o: HiServerImpl.cc HiServerImpl.hh Hi.hh
	$(CC) $(CPPFLAGS) $(INCLUDES) HiServerImpl.cc
                                                                                
nidl: Hi.idl
	$(OMNIIDL) -bcxx Hi.idl
                                                                                
clean:
	rm -f *.o
	rm -f *.bin

编译

make -f MakeServer

CPP实现CORBA静态绑定(二)

本文主要内容涉及:

  • CORBA基本架构
  • IDL文件编写
  • CPP示例实现(上)
  • CPP示例实现(下)
  • C示例实现(IOR+NS上)
  • C示例实现(IOR+NS下)
  • C示例实现(IOR上)
  • C示例实现(IOR下)

要写一个静态绑定的CORBA程序,首先要完成的就是定义接口。CORBA采用的接口描述方式为IDL(Interface Description Language),IDL的语法规则类似于CPP。

IDL与CPP常见类型映射关系如下:

IDL Type C++ Type Word size and range
short CORBA::Short 16 bit: -2^15 … +2^15 – 1
long CORBA::Long 32 bit: -2^31 … +2^31 – 1
long long CORBA::LongLong 64 bit: -2^63 … +2^63 – 1
unsigned short CORBA::UShort 16 bit: 0 … 2^16 – 1
unsigned long CORBA::ULong 32 bit: 0 … 2^32 – 1
unsigned long long CORBA::ULongLong 64 bit: 0 … 2^64
float CORBA::Float 32 bit IEEE single precision floating point number
double CORBA::Double 64 bit IEEE double precision floating point number
long double CORBA::LongDouble
char CORBA::Char 8 bit
wchar CORBA::WChar (Wide Char)
string CORBA::char *
wstring CORBA::WChar *
boolean CORBA::Boolean true/false
octet CORBA::Octet (unsigned char) 8 bit raw. No conversion.
any CORBA::Any Arbitrary

比如,下面就是一个很简单的IDL文件:
hi.idl

module HiCorba
{
	interface Hi
	{
		string sayHiTo(in string someone);
		long add(in long numa, in long numb);
		oneway void shutdown();
	};
};

CPP实现CORBA静态绑定(一)

本文主要内容涉及:

  • CORBA基本架构
  • IDL文件编写
  • CPP示例实现(上)
  • CPP示例实现(下)
  • C示例实现(IOR+NS上)
  • C示例实现(IOR+NS下)
  • C示例实现(IOR上)
  • C示例实现(IOR下)

CORBA(Common Object Request Broker Architecture),即公用对象请求代理程序体系结构,是一种为解决分布式处理环境中硬件和软件系统的互连而提出的一种解决方案。其基本架构如下:

Object Services,即对象服务,是为使用和实现对象而提供的基本对象集合,这些服务应独立于应用领域。主要的CORBA服务有:名录服务(Naming Service)、事件服务(Event Service)、生命周期服务(Life Cycle Service)、关系服务(Relationship Service)以及事务服务(Transaction Service)等。这些服务几乎包括分布系统和面向对象系统的各个方面,每个组成部分都非常复杂。

IDL(Interface Description Language),即接口定义语言,是用来描述软件组件接口的一种规范语言。用户可以定义模块、接口、属性、方法、输入输出参数,甚至异常等等。IDL在不同的语言下都有相应的实现,可以把IDL描述的接口编译为目标语言,包括客户端代理和服务器端框架,以及相应的帮助类等等。

ORB(Object Request Broker),即对象请求代理,是一个中间件,在对象间建立客户-服务器的关系。通过 ORB,一个客户可以很简单地使用服务器对象的方法而不论服务器是在同一机器上还是通过一个网络访问。ORB 截获调用然后负责找到一个对象实现这个请求,传递参数和方法,最后返回结果。客户不用知道对象在哪里,是什么语言实现的,他的操作系统以及其他和对象接口无关的东西。

CORBA按接口绑定方式,分为两大类,一类为动态绑定,一类为静态绑定。这里主要讲的是静态绑定。
在静态绑定时,客户端需要实现IDL Stubs,服务端需要实现IDL Skeleton。
在静态绑定中,CORBA在服务端实现IDL接口有两种方式,一种为继承模式(分为标准模式POA及兼容模式ImplBase),另一种为为委托模式(分为标准模式POA/Tie及兼容模式ImplBase/Tie)。各模式的区别主要在于生成IDL代码时,输入的参数不同,从而生成的接口不同,实现方式也略有区别。这里主要讲的为标准模式。

一次典型的CORBA调用,流程如下图所示:

GIOP(General Inter-ORB Protocol),即通用对象请求代理间通信协,提供了一个标准传输语法(低层数据表示方法)和ORB之间通信的信息格式集。GIOP只能用在ORB与ORB之间,而且,只能在符合理想条件的面向连接传输协议中使用。它不需要使用更高一层的RPC机制。这个协议是简单的(尽可能简单,但不是简单化),可升级的,使用方便。它被设计为可移动的、高效能的表现、较少依靠其它的低层传输协议。当然,由于不同传输使用不同版本的GIOP,它们可能不能直接协作工作,但它能很容易的连接网络域。

IIOP (Internet Inter-ORB Protocol),即Internet对象代理间通信协议,指出如何通过TCP/IP连接交换GIOP信息。IIOP为Internet提供了一个标准的协作工作协议,它使兼容的ORB能基于现在流行的协议和产品进行“out of the box”方式的协作工作。它也能被用于两个半桥(half-bridges )之间的协议。该协议能用于任何ORB与IP(Internet Protocol)域之间的协作工作,除非ORB选择了特殊的协议。这时,它是TCP/IP环境下基本的inter-ORB 协议,最普遍的传输层。

GIOP 不基于任何特别的网络协议,OMG 在最广泛使用的通信传输平台 — TCP/IP 上标准化 GIOP,GIOP 加 TCP/IP 等于 IIOP。

Java实现CORBA静态绑定(七)

本文主要内容涉及:

  • CORBA基本架构
  • IDL文件编写
  • POA示例实现
  • POA+TIE示例实现
  • ImplBase示例实现
  • ImplBase+TIE示例实现
  • Persistent示例实现

HiPersistent.idl

module HiCorba
{
	interface HiPersistent
	{
		string sayHiTo(in string someone);
		long add(in long numa, in long numb);
		oneway void shutdown();
	};
};

JDK提供了工具,可以直接生成stubs及skeletons接口代码:

idlj -fall HiPersistent.idl

编写server端代码:

import java.util.Properties;
import org.omg.CORBA.Object;
import org.omg.CORBA.ORB;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.CORBA.Policy;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.*;
import org.omg.PortableServer.Servant;
import HiCorba.*;

class HiPersistentImpl extends HiPersistentPOA {
	private ORB orb;
	public void setORB(ORB orb_val) {
		orb = orb_val;
	}
	// implement sayHiTo() method
	public String sayHiTo(String someone) {
		return "\nHi, "+someone+" !"+"\n";
	}
	// implement add() method
	public int add(int numa, int numb) {
		return numa+numb;
	}
	// implement shutdown() method
	public void shutdown() {
		orb.shutdown(false);
	}
}

public class HiPersistentServer {
	public static void main( String args[] ) {
		try {
			// Step 1: Instantiate the ORB
			ORB orb = ORB.init(args, null);

			// Step 2: Instantiate the servant
			HiPersistentImpl impl = new HiPersistentImpl();
		        impl.setORB(orb);

			// Step 3 : Create a POA with Persistent Policy
			// Step 3-1: Get the rootPOA 
			POA rootPOA = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
			// Step 3-2: Create the Persistent Policy
			Policy[] persistentPolicy = new Policy[1];
			persistentPolicy[0] = rootPOA.create_lifespan_policy(LifespanPolicyValue.PERSISTENT);
			// Step 3-3: Create a POA by passing the Persistent Policy
			POA persistentPOA = rootPOA.create_POA("childPOA", null, persistentPolicy ); 
			// Step 3-4: Activate HiPersistentPOA's POAManager, Without this
			// All calls to HiPersistent Server will hang because POAManager
			// will be in the 'HOLD' state.
			persistentPOA.the_POAManager().activate( );
			
			// Step 4: Associate the servant with HiPersistentPOA
			persistentPOA.activate_object( impl );

			// Step 5: Resolve RootNaming context and bind a name for the
			// servant.
			// NOTE: If the Server is persistent in nature then using Persistent
			// Name Service is a good choice. Even if ORBD is restarted the Name
			// Bindings will be intact. To use Persistent Name Service use
			// 'NameService' as the key for resolve_initial_references() when
			// ORBD is running.
			org.omg.CORBA.Object obj = orb.resolve_initial_references( "NameService" );
			NamingContextExt rootContext = NamingContextExtHelper.narrow( obj );

			NameComponent[] nc = rootContext.to_name( "HiPersistent" );
			rootContext.rebind( nc, persistentPOA.servant_to_reference( impl ) );

			// Step 6: We are ready to receive client requests
			orb.run();
		} catch ( Exception e ) {
			System.err.println( "Exception in Persistent Server Startup " + e );
		}
	}
}

编写client端代码:

import java.util.Properties;
import org.omg.CORBA.ORB;
import org.omg.CORBA.OBJ_ADAPTER;
import org.omg.CosNaming.NamingContext;
import org.omg.CosNaming.NamingContextHelper;
import org.omg.CosNaming.NameComponent;
import org.omg.PortableServer.POA;
import HiCorba.*;

public class HiPersistentClient {
	public static void main(String args[]) {
		try {
			// Step 1: Instantiate the ORB
			ORB orb = ORB.init(args, null);

			// Step 2: Resolve the PersistentHelloServant by using INS's
			// corbaname url. The URL locates the NameService running on
			// localhost and listening on 1900 and resolve 
			// 'PersistentServerTutorial' from that NameService
			org.omg.CORBA.Object obj = orb.string_to_object("corbaname::localhost:1900#HiPersistent");
			HiPersistent hiPersistent = HiPersistentHelper.narrow( obj );

			// Step 3: Call the sayHello() method every 60 seconds and shutdown
			// the server. Next call from the client will restart the server,
			// because it is persistent in nature.
			while( true ) {
				System.out.println( "Calling HiPersisten Server.." );
				System.out.println("Message From HiPersisten Server: " + hiPersistent.sayHiTo("neohope") );
				System.out.println("70 + 80 = " + hiPersistent.add(70, 80) );
				System.out.println( "Shutting down HiPersistent Server.." );
				hiPersistent.shutdown( );
				Thread.sleep(2000);
			}
		} catch ( Exception e ) {
			System.err.println( "Exception in HiPersistentClient.java..." + e );
			e.printStackTrace( );
		}
	}
}

编译代码:

javac *.java HiCorba/*.java

测试,在三个shell或cmd窗口中依次运行:

#shell01
orbd -ORBInitialPort 1900 -serverPollingTime 200
#shell02
servertool -ORBInitialPort 1900
>>欢迎使用 Java IDL 服务器工具
>>请在提示处输入命令
> register -server HiPersistentServer -applicationName s1 -classpath .
#shell03
java HiPersistentClient
>>Calling HiPersisten Server..
>>Message From HiPersisten Server:
>>Hi, neohope !
>>70 + 80 = 150
>>Shutting down HiPersistent Server..
>>
>>Calling HiPersisten Server..
>>Message From HiPersisten Server:
>>Hi, neohope !
>>70 + 80 = 150
>>Shutting down HiPersistent Server..

Java实现CORBA静态绑定(六)

本文主要内容涉及:

  • CORBA基本架构
  • IDL文件编写
  • POA示例实现
  • POA+TIE示例实现
  • ImplBase示例实现
  • ImplBase+TIE示例实现
  • Persistent示例实现

ImplBase主要是为了兼容旧代码所提供的,正常情况下,大家是不需要使用的。
JDK提供了工具,可以直接生成stubs及skeletons接口代码:

idlj -fall -oldImplBase Hi.idl
idlj -fallTie -oldImplBase Hi.idl

编写server端代码:

import HiCorba.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import java.util.Properties;

class HiImpl extends _HiImplBase{
	private ORB orb;
	public void setORB(ORB orb_val){
		orb = orb_val;
	}
	// implement sayHiTo() method
	public String sayHiTo(String someone) {
		return "\nHi, "+someone+" !"+"\n";
	}
	// implement add() method
	public int add(int numa, int numb) {
		return numa+numb;
	}
	// implement shutdown() method
	public void shutdown() {
		orb.shutdown(false);
	}
}

public class HiServer {
	public static void main(String args[]) {
		try{
			// create and initialize the ORB
			ORB orb = ORB.init(args, null);
			// create servant and register it with the ORB
			HiImpl hiImpl = new HiImpl();
			hiImpl.setORB(orb);
			// create a tie, with servant being the delegate.
			Hi_Tie tie = new Hi_Tie(hiImpl);
			// obtain the objectRef for the tie
			// this step also implicitly activates the object
			Hi href =  HiHelper.narrow(tie);
			// get the root naming context
			org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
			NamingContext ncRef = NamingContextHelper.narrow(objRef);
			// bind the Object Reference in Naming
			NameComponent nc = new NameComponent("Hi", "");
			NameComponent path[] = {nc};
			ncRef.rebind(path, href);
			System.out.println("HiServer ready and waiting ...");
			// wait for invocations from clients
			orb.run();
		}
		catch (Exception e) {
			System.err.println("ERROR: " + e);
			e.printStackTrace(System.out);
		}
		System.out.println("HiServer Exiting ...");
	}
}

编写client端代码:

import HiCorba.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;

public class HiClient{
	public static void main(String args[]){
		try{
			// create and initialize the ORB
			ORB orb = ORB.init(args, null);
			// get the root naming context
			org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
			NamingContext ncRef = NamingContextHelper.narrow(objRef);
			// resolve the Object Reference in Naming
			NameComponent nc = new NameComponent("Hi", "");
			NameComponent path[] = {nc};
			Hi hiImpl = HiHelper.narrow(ncRef.resolve(path));
			System.out.println("Obtained a handle on server object: " + hiImpl);
			System.out.println(hiImpl.sayHiTo("neohope"));
			System.out.println(hiImpl.add(70, 80));
			hiImpl.shutdown();
		}
		catch (Exception e) {
			System.out.println("ERROR : " + e) ;
			e.printStackTrace(System.out);
		}
	}
}

编译代码:

javac *.java HiCorba/*.java

测试,在三个shell或cmd窗口中依次运行:

#shell01
orbd -ORBInitialPort 1900
#shell02
java HiServer -ORBInitialPort 1900
>>HiServer ready and waiting ...
>>HiServer Exiting ...
#shell03
java HiClient -ORBInitialPort 1900 -ORBInitialHost localhost
>>Obtained a handle on server object: IOR:000000000000001349444c3a4869436f7262612f
  48693a312e30000000000001000000000000006e000102000000000d3139322e3136382e35362e31
  00007dfd00000019afabcb000000000276c739500000000800000001000000001400000000000002
  00000001000000200000000000010001000000020501000100010020000101090000000100010100
  00000026000000020002
>>Hi, neohope !
>>150