A real server : finally !!

Everything by hand

Once more, we'll code the FruitsBasket::Apple server. Without preliminaries, here is the code: every piece was already studied separately.

#include <orb/orbit.h>
#include <ORBitservices/CosNaming.h>

void MyEatMe (PortableServer_Servant servant, 
CORBA_Environment * ev)
{
/* 
	here is your own code which 
	corresponds to the object 
	implementation 
*/
}
void MyThrowMe (PortableServer_Servant servant, 
CORBA_Environment * ev)
{
/* 
	here is your own code which 
	corresponds to the object 
	implementation 
*/
}

PortableServer_ServantBase__epv base_epv {
	NULL, /* ORB specific data */
	NULL, /* finalize method */
	NULL  /* default POA */
}

POA_FruitsBasket_Apple__epv Apple_epv {
	NULL,    /* ORB specific data */
	MyEatMe,
	MyThrowMe
};

POA_FruitsBasket_Apple__vepv Apple_vepv {
	&base_epv,
	&Apple_epv
};

POA_FruitsBasket_Apple Apple_servant = {
	NULL,
	&Apple_vpev
};

int main (int argc, char **argv)
{
CORBA_Environment ev;
CORBA_ORB orb;
PortableServer_POA poa;
/* we use the default policies */
CORBA_PolicyList policy_list = {0, 0, NULL}; 
PortableServer_POA root_poa;
PortableServer_POAManager root_poa_manager;
ObjectId *obj_id;
CORBA_Object obj;
CosNaming_NamingContext *root_name;
CosNaming_NameComponent name_component[1] = { {"MyApple", "server"} };
CosNaming_Name name = {1, 1, name_component, CORBA_FALSE};

/* initialize the orb and the servant
CORBA_exception_init (&ev);
orb = CORBA_ORB_init (&argc,
	argv, 
	"orbit-local-orb", 
	&ev);

POA_FruitsBasket_Apple__init (orb, 
	Apple_servant, 
	&ev);
if (ev->_major != CORBA_NO_EXCEPTION) {
	fprintf (stderr, 
		"Error: exception during Servant initialization: %s\n", 
		CORBA_exception_id(&ev));
	exit (1);
}

/* initialize the poa */
root_poa = CORBA_ORB_resolve_initial_references (orb, 
	"RootPOA", 
	&ev);
root_poa_manager = PortableServer_POA_get_the_POAManager (root_poa, 
	&ev);
PortableServer_POAManager_activate (root_poa_manager, 
	&ev);
PortableServer_POA_create_poa (root_poa, 
	"my_own_poa", 
	root_poa_manager, 
	policy_list, 
	&ev);
poa = PortableServer_POA_find_poa (root_poa, 
	"my_own_poa", 
	&ev);
if (ev->_major != CORBA_NO_EXCEPTION) {
	fprintf (stderr, 
		"Error: exception during POA initialization: %s\n", 
		CORBA_exception_id(&ev));
	CORBA_exception_free (&ev);
	exit (1);
}


/* activate the object */
obj_id = PortableServer_POA_activate_object (poa,
	&Apple_servant,
	&ev);
/* get an object reference */
obj = PortableServer_POA_id_to_reference (poa,
	obj_id,
	&ev);

/* register the object against the naming service */
root_name = CORBA_ORB_resolve_initial_service (orb, 
	"NameService", 
	&ev);
if (ev->_major != CORBA_NO_EXCEPTION) {
	fprintf (stderr, 
		"Error: could not get name service: %s\n", 
		CORBA_exception_id(&ev));
	exit (1);
}
CosNaming_NamingContext_bind (root_amp, 
	&name, 
	obj, 
	&ev);
if (ev->_major != CORBA_NO_EXCEPTION) {
	fprintf (stderr, 
		"Error: could register object: %s\n", 
		CORBA_exception_id(&ev));
	exit (1);
}
CORBA_free (root_poa);
CORBA_exception_free (&ev);
/* pfew !! here we are !! */

return 0;
}

ORBit's skeletons

The code we just seen is rather generic: obviously, almost nothing is specific to the FruitsBasket::Apple interface except for the function implementation of the object's methods (this is however quite normal). Most of this code may be used in any other server with any other interface.

That is why ORBit provides an easy way to automatically generate the code I just spent a chapter explaining you. The --skeleton-impl option will generate a C file which contains sample server code. Here is for example the code generated for this FruitsBasket::Apple interface.

#include "apple.h"

/*** App-specific servant structures ***/
typedef struct {
	POA_FruitsBasket_Apple servant;
	PortableServer_POA poa;

} impl_POA_FruitsBasket_Apple;

/*** Implementation stub prototypes ***/
static void impl_FruitsBasket_Apple__destroy(impl_POA_FruitsBasket_Apple * servant,
	CORBA_Environment * ev);
static void
impl_FruitsBasket_Apple_EatMe(impl_POA_FruitsBasket_Apple * servant,
	CORBA_Environment * ev);

static void
impl_FruitsBasket_Apple_ThrowMe(impl_POA_FruitsBasket_Apple * servant,
	CORBA_Environment * ev);

/*** epv structures ***/
static PortableServer_ServantBase__epv impl_FruitsBasket_Apple_base_epv =
{
	NULL,			/* _private data */
	NULL,			/* finalize routine */
	NULL,			/* default_POA routine */
};
static POA_FruitsBasket_Apple__epv impl_FruitsBasket_Apple_epv =
{
	NULL,			/* _private */
	(gpointer) & impl_FruitsBasket_Apple_EatMe,
	(gpointer) & impl_FruitsBasket_Apple_ThrowMe,

};

/*** vepv structures ***/
static POA_FruitsBasket_Apple__vepv impl_FruitsBasket_Apple_vepv =
{
	&impl_FruitsBasket_Apple_base_epv,
	&impl_FruitsBasket_Apple_epv,
};

/*** Stub implementations ***/
static FruitsBasket_Apple
impl_FruitsBasket_Apple__create(PortableServer_POA poa, 
	CORBA_Environment * ev)
{
FruitsBasket_Apple retval;
impl_POA_FruitsBasket_Apple *newservant;
PortableServer_ObjectId *objid;

newservant = g_new0(impl_POA_FruitsBasket_Apple, 1);
newservant->servant.vepv = &impl_FruitsBasket_Apple_vepv;
newservant->poa = poa;
POA_FruitsBasket_Apple__init((PortableServer_Servant) newservant, ev);
objid = PortableServer_POA_activate_object(poa, newservant, ev);
CORBA_free(objid);
retval = PortableServer_POA_servant_to_reference(poa, newservant, ev);

return retval;
}

static void
impl_FruitsBasket_Apple__destroy(impl_POA_FruitsBasket_Apple * servant,
				 CORBA_Environment * ev)
{
PortableServer_ObjectId *objid;

objid = PortableServer_POA_servant_to_id(servant->poa, servant, ev);
PortableServer_POA_deactivate_object(servant->poa, objid, ev);
CORBA_free(objid);

POA_FruitsBasket_Apple__fini((PortableServer_Servant) servant, ev);
g_free(servant);
}

static void
impl_FruitsBasket_Apple_EatMe(impl_POA_FruitsBasket_Apple * servant,
			      CORBA_Environment * ev)
{
}

static void
impl_FruitsBasket_Apple_ThrowMe(impl_POA_FruitsBasket_Apple * servant,
				CORBA_Environment * ev)
{
}

The only thing left to do is to implement a main function which calls the create function and initializes a few things...

Note that this code uses the trick presented in the precedent section to associate PortableServer_POA POA to the servant by the mean of the following structure

typedef struct {
	POA_FruitsBasket_Apple servant;
	PortableServer_POA poa;

} impl_POA_FruitsBasket_Apple;