Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Indice
1. Introducci
on
2. Descarga y copia
3. Variables de entorno
4. Primeros pasos
4.1. Fichero IDL . .
4.2. Cliente . . . . .
4.3. Implementaci
on
4.4. El servidor . .
4.5. Makefile . . . .
4.6. Ejecucion . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
. 4
. 5
. 6
. 8
. 10
. 12
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. .
. .
del
. .
. .
. .
. . . . .
. . . . .
servant
. . . . .
. . . . .
. . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6. Revisi
on
1.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
13
13
14
14
15
19
25
26
27
Introducci
on
Este documento explica los primeros pasos para usar ORBacus en su versi
on para
C++. Este software se utilizar
a en las practicas de la asignatura. ORBacus es una
implementaci
on de CORBA de las m
as flexibles y mejor implementadas. Adem
as, aunque
no es gratis, su codigo esta disponible para ser usado en universidades sin cargo. Existen
otros totalmente libres, pero ORBacus ofrece la solucion m
as sencilla y m
as potente a
la vez. Este documento muestra como descargar, compilar y un ejemplo sencillo de uso
con ORBacus.
2.
Descarga y copia
El directorio de instalaci
on puede ser el que el usuario elija, como por ejemplo
/usr/local. A partir de ahora lo llamaremos $ORBACUS.
Finalmente, debemos ejecutar:
dsevilla@neuromancer:~/prog/ob/OB-4.1.0$ . ./go
Eso ejecuta una serie de comprobaciones necesarias para poder compilar el software.
Finalmente, hay que ejecutar make install min, que construye ORBacus y lo instala
3.
Variables de entorno
4.
Primeros pasos
4.1.
Fichero IDL
interface Hola
{
string dihola ( in long num ) ;
};
idl Hola.idl
Esto genera los ficheros de stub (Hola.h y Hola.cpp) y skeleton (Hola skel.h y
Hola skel.cpp).
4.2.
Cliente
A continuaci
on se muestra el cliente (cliente.cpp): Es un programa que es capaz de
utilizar el objeto Hola:
2
# include
# include
# include
# include
10
12
14
16
18
20
22
int
main ( int argc , char ** argv )
{
try {
// Iniciar el ORB
CORBA :: ORB_var orb = CORBA :: ORB_init ( argc , argv ) ;
// Recuperar la cadena de caracteres de la l
nea
// de comandos que guarda el IOR y convertirla
// en una referencia a un objeto CORBA
CORBA :: String_var s ;
CORBA :: Object_var o = orb - > string_to_object ( argv [1]) ;
// Obtener el n
u mero de la l
nea de comandos
CORBA :: Long i = atol ( argv [2]) ;
24
26
28
30
32
34
36
// Llamar al m
e todo dihola usando la referencia al objeto
s = h - > dihola ( i ) ;
std :: cout << s << std :: endl ;
} catch (...)
{
std :: cerr << " quietorl ! " << std :: endl ;
}
}
38
4.3.
Implementaci
on del servant
Para implementar un objeto CORBA, esto es, para ofrecer sus servicios al mundo, se
tienen que implementar dos cosas:
El servant que contiene la implementaci
on de los metodos del interfaz que se ofrece
al exterior,
y un servidor, que quedar
a esperando conexiones en un puerto IP.
El servant es simplemente un objeto del lenguaje de programaci
on (en este caso C++)
que implementa la funcionalidad de los metodos del objeto CORBA. Este servant es
llamado por el skeleton cuando un cliente llama a un metodo del objeto CORBA implementado por ese servant.
El compilador de IDL de ORBacus ofrece la posibilidad de generar automaticamente
una implementaci
on vaca del servant que podra modificar el programador para implementar las operaciones. Este esqueleto vaco se genera ejecutando:
idl --impl Hola.idl
Esto genera dos ficheros vacos: Hola impl.h y Hola impl.cpp. A continuaci
on se
lista el fichero Hola impl.h:
1
# ifndef ___Hola_impl_h__
# define ___Hola_impl_h__
11
13
//
// IDL : Hola :1.0
//
class Hola_impl : virtual public POA_Hola ,
virtual public PortableServer ::
RefCountServantBase
{
Hola_impl ( const Hola_impl &) ;
void operator =( const Hola_impl &) ;
PortableServer :: POA_var poa_ ;
15
17
public :
Hola_impl ( PortableServer :: POA_ptr ) ;
~ Hola_impl () ;
19
21
//
// IDL : Hola / dihola :1.0
//
virtual char * dihola ( CORBA :: Long num )
throw ( CORBA :: SystemException ) ;
25
27
29
};
31
# endif
33
//
// IDL : Hola :1.0
//
Hola_impl :: Hola_impl ( PortableServer :: POA_ptr poa )
: poa_ ( PortableServer :: POA :: _duplicate ( poa ) )
{
}
11
13
{
}
15
17
19
PortableServer :: POA_ptr
Hola_impl :: _default_POA ()
{
return PortableServer :: POA :: _duplicate ( poa_ ) ;
}
21
23
25
27
29
//
// IDL : Hola / dihola :1.0
//
char *
Hola_impl :: dihola ( CORBA :: Long num )
throw ( CORBA :: SystemException )
{
char * _r = CORBA :: string_alloc (4 * num + 1) ;
for ( size_t i = 0; i < num ; ++ i )
strcpy ( _r + 4* i , " Hola " ) ;
31
33
return _r ;
35
37
4.4.
El servidor
En cualquier aplicacion CORBA debe existir un servidor que quede esperando las
peticiones sobre los objetos CORBA implementados por el (servants). El servidor es un
programa C++ normal que dejara activado un servant para el objeto CORBA.
1
11
13
int
main ( int argc , char * argv [] , char *[])
{
CORBA :: ORB_var orb ;
15
17
try
{
orb = CORBA :: ORB_init ( argc , argv ) ;
19
//
// Obtener el POA ra
z
//
CORBA :: Object_var poaObj = orb - > r e s o l v e _ i n i t i a l _ r e f e r en c e s ( "
RootPOA " ) ;
PortableServer :: POA_var rootPOA = PortableServer :: POA :: _narrow
( poaObj ) ;
21
23
25
//
// Obtener el POA manager
//
PortableServer :: POAManager_var manager = rootPOA - >
the_POAManager () ;
27
29
//
// Crear el objeto implementaci
on
//
Hola_impl * hImpl = new Hola_impl ( rootPOA ) ;
CORBA :: Object_var o = rootPOA - > s e r v a n t _ t o _ r e f e r e n c e ( hImpl ) ;
Hola_var hola = Hola :: _narrow ( o ) ;
31
33
35
37
//
// Grabar la referencia en un fichero
//
CORBA :: String_var s = orb - > object_to_string ( hola ) ;
39
41
43
45
47
49
51
53
//
// Ejecutar la implementaci
on
//
manager - > activate () ;
orb - > run () ;
55
57
59
return 0;
}
catch ( const CORBA :: Exception & ex )
{
cerr << ex << endl ;
return 1;
}
61
63
65
67
69
4.5.
Makefile
Es importante construir un buen fichero Makefile, debido a que se tienen que utilizar
varios programas y generar varios ficheros, por lo que el fichero para el programa make no
es trivial. A continuaci
on se muestra un fichero Makefile para el ejemplo que estamos
considerando:
1
# Makefile
#
# Suponemos que la variable ORBACUS est
a definida en el entorno , y
que
# el compilador de IDL est
a dentro de los directorios listados en
la variable
# $PATH . Si no , otra alternativa ser
a utilizar $ORBACUS / bin / idl
10
#
CPPFLAGS = - I$ ( ORBACUS ) / include -I .
LDFLAGS = - L$ ( ORBACUS ) / lib
LIBS = - lOB - lJTC - lpthread - ldl
15
17
19
$ ( GENFILES ) : $ ( IDLFILE )
21
11
13
23
25
27
# Parte gen
e rica
29
31
33
35
clean :
rm - rf cliente servidor $ ( GENFILES ) *. o core *~ . depend
. depend :
$ ( CPP ) $ ( CPPFLAGS ) - MM - MG *. cpp 2 >/ dev / null > $@
37
- include . depend
39
Las libreras utilizadas son parte del ORB (OB y JTC), adem
as de las libreras necesarias
para ese ORB en Linux (-lpthread, -ldl).
La ejecuci
on de make genera una salida como la siguiente:
$ make
gcc -E -I/opt2/corbalc/orbs/orbacus/include -I. -MM -MG *.cpp > .depend
idl Hola.idl
g++ -I/opt2/corbalc/orbs/orbacus/include -I. -c -o cliente.o cliente.cpp
g++ -I/opt2/corbalc/orbs/orbacus/include -I. -c -o Hola.o Hola.cpp
g++ -o cliente -L/opt2/corbalc/orbs/orbacus/lib -lOB -lJTC -lpthread
-ldl cliente.o Hola.o
g++ -I/opt2/corbalc/orbs/orbacus/include -I. -c -o servidor.o servidor.cpp
g++ -I/opt2/corbalc/orbs/orbacus/include -I. -c -o Hola_skel.o Hola_skel.cpp
g++ -I/opt2/corbalc/orbs/orbacus/include -I. -c -o Hola_impl.o Hola_impl.cpp
g++ -o servidor -L/opt2/corbalc/orbs/orbacus/lib -lOB -lJTC -lpthread
11
4.6.
Ejecuci
on
La ejecuci
on de la aplicacion necesita primero de la ejecuci
on del servidor. Tal y como
se ha visto, el servidor crea un fichero llamado Hola.ref, en el que introduce el IOR del
objeto servidor. En principio ejecutaremos el cliente y el servidor en la misma m
aquina,
aunque usando el IOR, que se puede transmitir por correo o por cualquier otro medio,
el cliente podra utilizar nuestro objeto servidor desde cualquier otro ordenador. La
ejecuci
on1 :
$ ./servidor &
Esto crea el fichero Hola.ref:
IOR:01dc05080d00000049444c3a486f6c613a312e30003d6040010000000000000
078000000010102000a0000006c6f63616c686f7374003b8525000000abacab3131
303636373432323731005f526f6f74504f410000cafebabe3f9531ff00000000000
00001000000010000002c0000000116000001000100040000002000010009010100
000101000100010509010100020000000001010001000105
Como curiosidad, el programa iordump (tambien perteneciente a ORBacus), permite
obtener los datos del IOR:
$ iordump cat Hola.ref
IOR #1:
byteorder: little endian
type_id: IDL:Hola:1.0
Profile #1: iiop
iiop_version: 1.2
host: localhost
port: 34107
object_key: (37)
171 172 171 49 49 48 54 54 "...11066"
55 52 50 50 55 49
0 95 "742271._"
82 111 111 116 80 79 65
0 "RootPOA."
0 202 254 186 190 63 149 49 ".....?.1"
255
0
0
0
0
"....."
Native char code set:
"ISO 8859-1:1987; Latin Alphabet No. 1"
Char conversion code sets:
"ISO 646:1991 IRV (International Reference Version)"
"ISO/IEC 10646-1:1993; UTF-16, UCS Transformation Format 16-bit form"
1
En el caso de que el ordenador no tenga bien configurada la red, se puede utilizar el comando de
ejecuci
on ./servidor -OAhost localhost & (la opci
on -OAhost especifica la IP a utilizar).
12
5.
5.1.
ORBacus incluye una librera de threads llamada JTC (Java-Threads for C++). Su
uso es muy similar a los hilos de Java. As, al crear una clase C++ se le puede especificar
que es un thread:
# include < JTC / JTC .h >
2
Los threads tambien ofrecen las operaciones isAlive() y terminate(), para comprobar si el hilo se esta ejecutando y para terminarlo en su caso.
Los hilos se pueden convertir en monitores para permitir que se bloqueen y para
permitir hacer secciones crticas:
2
10
13
12
14
16
};
El metodo ((m
etodo)) es una secci
on crtica. Nadie podra ejecutarlo si ya se esta ejecutando. Las clases JTCSynchronized siguen el patron ((reserva de recursos en creaci
on)),
as que cuando sale de
ambito la variable se elimina el lock sobre el candado.
Vease tambien Henning & Vinoski, cap. 21, aunque ah utilizan ACE (Adaptative
Communication Envionment, Schmidt et al., http://www.cs.wustl.edu/~schmidt).
5.2.
El ejemplo
5.3.
Definiciones IDL
Las definiciones IDL son basicas. Primero las estructuras comunes. Muestran los datos
que genera el sensor y que se transmiten entre los clientes suscritos y el servidor (fichero
SensorData.idl):
1
# ifndef SENSOR_DATA
# define SENSOR_DATA
struct SensorData
{
long windspeed ;
long other ;
};
# endif
11
14
// Run sensor
void run () ;
10
};
12
interface SensorListener
{
oneway void nueva_lectura ( in SensorData v ) ;
};
Este u
ltimo fichero define el listener. Como se ve, la funcion de notificaci
on es ((oneway)).
Este dise
no suele ser el usual en aplicaciones de este tipo. Sin embargo, si se quiere asegurar que no se pierden mensajes, el metodo de notificaci
on podra ser un metodo normal,
no oneway.
5.4.
El cliente
Como se ha dicho, en este caso, tanto el cliente como el servidor deben esperar peticiones: el servidor peticiones de a
nadir listeners; el cliente informaciones del sensor a traves
del metodo nueva lectura. As, el cliente debe implementar el objeto SensorListener
para que el servidor pueda informarle de cambios en sl sensor. La implementaci
on no
tiene grandes problemas y es sencilla:
2
# ifndef _ _ _ S e n s o r L i s t e n e r _ i m p l _ h _ _
# define _ _ _ S e n s o r L i s t e n e r _ i m p l _ h _ _
//
// IDL : SensorListener :1.0
//
class SensorListener_impl : virtual public POA_SensorListener ,
virtual public PortableServer ::
RefCountServantBase
{
SensorListener_impl ( const SensorListener_impl &) ;
void operator =( const SensorListener_impl &) ;
10
12
14
15
public :
20
22
24
26
//
// IDL : SensorListener / nueva_lectura :1.0
//
virtual void nueva_lectura ( const SensorData & v )
throw ( CORBA :: SystemException ) ;
28
30
};
32
# endif
1
11
13
15
17
19
21
PortableServer :: POA_ptr
SensorListener_impl :: _default_POA ()
{
return PortableServer :: POA :: _duplicate ( poa_ ) ;
}
23
25
27
29
31
//
// IDL : SensorListener / nueva_lectura :1.0
//
void
SensorListener_impl :: nueva_lectura ( const SensorData & v )
throw ( CORBA :: SystemException )
{
std :: cerr << " Recibido evento ( " << id_
<< " ) . windspeed = " << v . windspeed
16
33
35
37
El metodo nueva lectura, cuando es llamado por el servidor, imprime los valores en
la salida estandar.
1
// -* - mode : c ++; c - basic - offset : 8; -* # include < OB / CORBA .h > // Incluir las definiciones de ORBacus
# include " SensorListener . h "
// Incluir el " stub "
# include " Sensor . h "
# include " SensorData . h "
# include " SensorListener_impl . h "
# include < iostream >
# include < stdlib .h >
# include < vector >
11
13
15
17
19
21
23
25
int
main ( int argc , char ** argv )
{
try {
ImplVector iv ( NUM_LISTENERS ) ;
PtrVector pv ( NUM_LISTENERS ) ;
// Iniciar el ORB
CORBA :: ORB_var orb = CORBA :: ORB_init ( argc , argv ) ;
27
29
31
33
//
// Obtener el POA ra
z
//
CORBA :: Object_var poaObj =
orb -> r e s o l v e _ i n i t i a l _ r e f e r e n c e s ( " RootPOA " ) ;
PortableServer :: POA_var rootPOA =
PortableServer :: POA :: _narrow ( poaObj ) ;
35
37
39
//
// Obtener el POA manager
//
PortableServer :: POAManager_var manager =
rootPOA -> the_POAManager () ;
41
43
//
// Ejecutar la implementaci
on
//
17
45
47
49
51
53
55
57
59
61
63
65
67
//
// Crear mil objetos listener
//
for ( CORBA :: ULong i = 0; i < NUM_LISTENERS ; i ++)
{
SensorListener_impl * hImpl =
new SensorListener_impl ( rootPOA , i ) ;
CORBA :: Object_var o =
rootPOA -> s e r v a n t _ t o _ r e f e r e n c e ( hImpl ) ;
SensorListener_var listener =
SensorListener :: _narrow ( o ) ;
iv [ i ] = hImpl ;
pv [ i ] = listener ;
69
// A~
n adir el listener al sensor
s - > addListener ( listener . in () ) ;
71
}
73
75
s - > run () ;
77
79
81
83
85
87
89
91
93
95
97
18
99
101
El cliente es algo m
as complejo. B
asicamente:
1. Crea 1000 listeners.
2. Los registra con el sensor (lneas 5972).
3. Inicia el sensor (lnea 75).
4. Desregistra y desactiva los listeners (lneas 7994).
Para ello, mantiene dos listas: iv, que guarda un array de servants y pv, que guarda
un array de punteros a objetos CORBA (los listeners).
5.5.
La implementaci
on del servidor del sensor
Empecemos con la definicion del fichero de cabeceras C++ del sensor (Sensor impl.h):
1
# ifndef ___Sensor_impl_h__
# define ___Sensor_impl_h__
13
15
17
19
//
// IDL : Sensor :1.0
//
class Sensor_impl : virtual public POA_Sensor ,
virtual public PortableServer ::
RefCountServantBase
{
Sensor_impl ( const Sensor_impl &) ;
void operator =( const Sensor_impl &) ;
21
23
ListenerList ll_ ;
25
27
public :
Sensor_impl ( PortableServer :: POA_ptr ) ;
~ Sensor_impl () ;
29
19
//
// IDL : Sensor / addListener :1.0
//
virtual void addListener ( SensorListener_ptr listener )
throw ( CORBA :: SystemException ) ;
33
35
37
//
// IDL : Sensor / removeListener :1.0
//
virtual void removeListener ( SensorListener_ptr listener )
throw ( CORBA :: SystemException ) ;
39
41
43
//
// IDL : Sensor / run :1.0
//
virtual void run ()
throw ( CORBA :: SystemException ) ;
45
47
49
};
51
# endif
El fichero de implementaci
on del servant es algo m
as complicado. Se muestra a continuaci
on (despues del listado se explica detalladamente):
1
11
13
public :
15
17
// M
e todo run del thread
void run ()
{
sl_ - > nueva_lectura ( d_ ) ;
}
19
21
23
};
25
27
29
20
ThreadList tl_ ;
31
public :
void notify ( const ListenerList & ll , const SensorData & d )
{
for ( ListenerList :: const_iterator it = ll . begin () ,
end = ll . end () ;
it != end ; it ++)
{
JTCThreadHandle ln = new ListenerNotifier
(* it , d ) ;
ln -> start () ;
33
35
37
39
41
tl_ . push_back ( ln ) ;
43
45
// Sincronizaci
o n final . Se utiliza el m
e todo "
join "
// para esperar a que terminen los threads .
for ( ThreadList :: const_iterator it = tl_ . begin () ,
end = tl_ . end () ;
it != end ; it ++)
{
do
{
try {
(* it ) -> join () ;
} catch ( const
J T C I n t e r r u p t e d E x c e p t i o n &)
{
}
} while ((* it ) -> isAlive () ) ;
}
47
49
51
53
55
57
59
}
61
};
63
65
67
69
//
// IDL : Sensor :1.0
//
Sensor_impl :: Sensor_impl ( PortableServer :: POA_ptr poa )
: poa_ ( PortableServer :: POA :: _duplicate ( poa ) )
{
}
71
73
75
77
79
21
}
81
83
PortableServer :: POA_ptr
Sensor_impl :: _default_POA ()
{
return PortableServer :: POA :: _duplicate ( poa_ ) ;
}
85
87
89
91
93
95
97
//
// IDL : Sensor / addListener :1.0
//
void
Sensor_impl :: addListener ( SensorListener_ptr listener )
throw ( CORBA :: SystemException )
{
// TODO : Comprobar duplicados
ll_ . push_back ( SensorListener :: _duplicate ( listener ) ) ;
}
99
101
103
105
107
109
111
113
115
117
119
121
123
125
127
//
// IDL : Sensor / removeListener :1.0
//
void
Sensor_impl :: removeListener ( SensorListener_ptr listener )
throw ( CORBA :: SystemException )
{
// OJO : Este c
o digo no es seguro , por los problemas de
identidad
// en CORBA .
for ( ListenerList :: iterator it = ll_ . begin () , end = ll_ .
end () ;
it != end ; it ++)
{
if ( listener - > _is_equivalent (* it ) )
{
CORBA :: release (* it ) ;
ll_ . erase ( it ) ;
break ;
}
}
}
//
// IDL : Sensor / run :1.0
//
void
Sensor_impl :: run ()
throw ( CORBA :: SystemException )
{
std :: cerr << " Servidor : comenzando " << std :: endl ;
129
131
22
135
L i s t e n e r G r o u p N o t i f i e r lgn ;
lgn . notify ( ll_ , * d ) ;
137
delete d ;
std :: cerr << " Servidor : finalizado " << std :: endl ;
139
}
141
La implementaci
on del sensor crea un hilo para notificar a cada listener. N
otese que
el crear tantos hilos como elementos a notificar es un riesgo, por lo que se tendran que
idear otras tecnicas, como un conjunto de hilos fijo, etc. Esto se deja como ejercicio.
La clase que implementa ese hilo es ListenerNotifier (lnea 8). ORBacus utiliza
la librera JTC (Java-Threads for C++). As, los hilos son parecidos a los de Java:
heredan de JTCThread y tiene un metodo run. Cada clase ListenerNotifier tiene un
SensorListener al que enva los datos del sensor.
La clase ListenerGroupNotifier es una abstraccion para una comunicaci
on de grupo.
Crea todos los hilos, creando cada uno de los objetos ListenerNotifier (hilos). Cada
uno de los hilos se inicia con start (lnea 40), y se almacenan en una lista de hilos (tl ).
Esta lista guarda objetos de tipo JTCThreadHandle. Estos objetos son handlers para
los hilos que manejan la memoria de los mismos (no hace falta destruirlos, se destruyen
automaticamente al salir de
ambito, como el idiom de adquisicion de recurso en creaci
on).
El siguiente bucle (lneas 4759), utiliza la funcion join para esperar a que todos los
hilos terminen.
Las funciones addListener y removeListener no tienen mucho problema. Su implementaci
on es normal.
Por u
ltimo, el metodo run enva un evento de datos al grupo de los listeners utilizando
la clase ListenerGroupNotifier.
En cuanto al servidor, simplemente crea y activa el objeto Sensor:
# include < OB / CORBA .h >
2
10
12
int
main ( int argc , char * argv [] , char *[])
{
CORBA :: ORB_var orb ;
14
16
try
{
orb = CORBA :: ORB_init ( argc , argv ) ;
23
18
//
// Obtener el POA ra
z
//
CORBA :: Object_var poaObj = orb -> r e s o l v e _ i n i t i a l _ r e f e r en c e s ( "
RootPOA " ) ;
PortableServer :: POA_var rootPOA = PortableServer :: POA :: _narrow
( poaObj ) ;
20
22
24
//
// Obtener el POA manager
//
PortableServer :: POAManager_var manager = rootPOA ->
the_POAManager () ;
26
28
//
// Crear el objeto implementaci
on
//
Sensor_impl * hImpl = new Sensor_impl ( rootPOA ) ;
CORBA :: Object_var o = rootPOA -> s e r v a n t _ t o _ r e f e r e n c e ( hImpl ) ;
Sensor_var sensor = Sensor :: _narrow ( o ) ;
30
32
34
36
//
// Grabar la referencia en un fichero
//
CORBA :: String_var s = orb -> object_to_string ( sensor ) ;
38
40
42
44
46
48
50
52
//
// Ejecutar la implementaci
on
//
manager -> activate () ;
orb -> run () ;
54
56
58
return 0;
}
catch ( const CORBA :: Exception & ex )
{
cerr << ex << endl ;
return 1;
}
60
62
64
66
24
68
5.6.
Makefiles
Por u
ltimo, veamos los ficheros make. Estos ejemplos de makefiles son algo m
as sofisticados que los anteriores. Primero, el fichero Make.rules guarda las reglas generales
para los ficheros IDL. Los dos macros, idlrule y process idls, generan las reglas (en
tiempo de ejecuci
on) para cada fichero IDL a partir de la variable $(IDLFILES):
# -* - Makefile -* - vim : set ft = make :
2
10
12
14
16
20
clean :
rm - rf $ ( CLEANFILES )
22
El resto de Makefile incluye a este fichero, y describe las reglas para compilar cliente
y servidor.
10
# Makefile
#
# Suponemos que la variable ORBACUS est
a definida en el entorno , y
que
# el compilador de IDL est
a dentro de los directorios listados en
la variable
# $PATH . Si no , otra alternativa ser
a utilizar $ORBACUS / bin / idl
#
DEBUG = - g
CPPFLAGS = - I$ ( ORBACUS ) / include -I . $ ( DEBUG )
LDFLAGS = - L$ ( ORBACUS ) / lib
LIBS = - lOB - lJTC - lpthread - ldl
12
14
25
16
18
20
22
24
26
28
# Parte gen
e rica
30
32
. depend :
$ ( CPP ) $ ( CPPFLAGS ) - MM - MG *. cpp 2 >/ dev / null > $@
34
- include . depend
36
5.7.
Configuraci
on de Threads en ORBacus
26
6.
Revisi
on
27