ARQUITECTURA CORBA ■ CORBA ■ ■ ■ ■ ■ ■ ■ Angel García Baños ➨ Escuela de Ingeniería de Sistemas y Computación ■ Universidad del Valle ■ 27 de Noviembre de 2002 CORBA 3 ■ El tipo any ■ ■ Mapeo del tipo any en C++ Códigos de tipos (TypeCode) ➨ ■ 3 Mapeo del tipo any en C++ ■ ■ ■ 2 El tipo any AGB ■ Extensión CORBA del Object Model de OMA. Estructura del ORB. Lenguaje de definición de interfases (IDL). Mapeo del IDL en lenguajes de programación. La interfase de Object. La interfase con el ORB. Los adaptadores de objetos (BOA y POA). Depósito de implementaciones (IMR). El tipo any. Depósito de interfases (IR). Interfase dinámica (DII y DSI). Interoperabilidad (GIOP, IIOP). AGB CORBA::TypeCode Valor AGB 4 Mapeo del tipo any en C++ El tipo any es un contenedor que almacena cualquier tipo de dato CORBA junto con su descripción de tipo. Para ello usa un descriptor de tipos TypeCode. Ello permite enviar y recibir valores no determinados en tiempo de compilación. Ejemplo: el servicio de eventos envía datos sin saber que son. También se usa any en la interfase dinámica (DII y DSI). Es similar a void * en lenguaje C, pero con manejo de tipos. Si se intenta leer un tipo de dato distinto al any que se escribió, da error. AGB Mapeo del tipo any en C++ Códigos de tipos (TypeCode) 5 ■ Con any se pueden hacer interfases genéricas. Por ejemplo: interface Universal { void escribir(in string nombre, in any valor); any leer(in string nombre); }; ■ También se pueden hacer listas de parámetros de longitud y tipo variables, como en printf(): struct Comodin { string name; any valor; }; typedef sequence<Comodin> ListaVariable; interface Variable { void operación(in ListaVariable parametros); AGB }; 6 Mapeo del tipo any en C++ ■ ■ ■ Mapeo del tipo any en C++ // Operadores de inserción para char, octect, strings limitados y fixed: void operator <<= (from_boolean); // from_boolean es un tipo auxiliar void operator <<= (from_char); // from_char es un tipo auxiliar void operator <<= (from_octect); // from_octect es un tipo auxiliar El tipo any no solo sirve para chequear tipos en tiempo de ejecución, sino que también permite introspección. Pero any es bastante ineficiente comparado con los tipos estáticos, ya que todas las operaciones involucradas las realiza en tiempo de ejecución. El tipo any en IDL se mapea al tipo CORBA::Any de C++. // etc. // Operadores de extracción para char, octect, strings limitados y fixed: Boolean operator >>= (to_boolean) const; // to_boolean es un tipo auxiliar Boolean operator >>= (to_char) const; // to_char es un tipo auxiliar Boolean operator >>= (to_octect) const; // to_octect es un tipo auxiliar Class Any // C++ { public: // Constructores, destructor y asignación: Any(); Any(const Any &); // Constructor de copia. Hace copia profunda ~Any(); Any & operator = (const Any &); // Hace copia profunda // etc. // Operadores de inserción para tipos simples: void operator <<= (CORBA::Any &, Short); void operator <<= (CORBA::Any &, UShort); void operator <<= (CORBA::Any &, Long); // etc. // Operadores de extracción para tipos simples: Boolean operator >>= (const CORBA::Any &, Short &) const; // etc. 7 AGB Mapeo del tipo any en C++ ■ // etc. CORBA::Any b; // Se crea un Any vacío b <<= (CORBA::UShort)88; // Inserta un UShort de valor 88 CORBA::Long x; if(!(a >>= x)) // Devuelve false ya que la extracción de un Long no tuvo éxito cout<<“Error”; Ejemplos de inserción de tipos simples: CORBA::Any a; // Se crea un Any vacío a <<= (CORBA::UShort)88; // Inserta un Ushort de valor 88 a <<= “Hola”; // Extrae el valor anterior e inserta el string “Hola” (deep copy) a <<= (CORBA::Double)2.73; // Extrae el string e inserta en su lugar un Double a <<= 35; // MAL. No queda claro el tipo. No es portable. CORBA::ULong x = 35; a <<= x; // BIEN. 9 AGB Mapeo del tipo any en C++ AGB 10 Mapeo del tipo any en C++ Los tipos que no se pueden distinguir entre sí (boolean, octect, char) necesitan usar funciones de inserción y extracción especiales: CORBA::Any a; // Se crea un Any vacío CORBA::Boolean b = true; CORBA::Char c = ‘a’; CORBA::Octect o = 0xA3; a <<= CORBA::Any::from_boolean(b); a <<= CORBA::Any::from_char(c); a <<= CORBA::Any::from_octect(o); CORBA::Boolean x; if(!(a >>= CORBA::Any::to_boolean(x))) cout<<“Error”; Ejemplos de extracción de tipos simples: CORBA::Any a; // Se crea un Any vacío a <<= (CORBA::UShort)88; // Inserta un UShort de valor 88 CORBA::UShort x; if(!(a >>= x)) // Devuelve true ya que la extracción de un UShort tuvo éxito cout<<“Error”; } ■ 8 Mapeo del tipo any en C++ // Operador de inserción para referencias: void operator <<= (from_object) const; // from_object es un tipo auxiliar // Operador de extracción para referencias: Boolean operator >>= (to_object) const; // to_object es un tipo auxiliar // Lectura y modificación de TypeCode: TypeCode_ptr type() const; void type(TypeCode_ptr); ■ AGB ■ // Devuelve false ya que es octec Para insertar y extraer strings limitados e ilimitados: CORBA::Any a; // Se crea un Any vacío a <<= “Hola”; // string ilimitado const char * texto; // Debe ser const, ya que apunta dentro de Any a >>= texto; // Any sigue siendo propietaria del string (lo libera al destruirse) CORBA::Any b, c; // Hace copia profunda. Si tamaño máximo de string = 0 ==> es ilimitado: b <<= CORBA::Any::from_string(“Hola”, 30); // String limitado a 30 letras char *str = new char[5]; strcpy(str, “Hola”); // Hace copia superficial tomando propiedad del string (tercer argumento = 1): c <<= CORBA::Any::from_string(str, 5, 1); // String limitado a 5 letras char *msj; b >>= CORBA::Any::to_string(msj, 30); // Hay que dar exactamente el tamaño AGB 11 AGB 12 Mapeo del tipo any en C++ Mapeo del tipo any en C++ Para insertar y extraer estructuras, uniones y secuencias, el operador de inserción está sobrecargado dos veces (una para inserción por referencia y otra para inserción por puntero): ■ struct Fecha { short dia; string mes; }; Insertar y extraer arrays. Ya que los arrays son punteros, para distinguir los de distinto tamaño el compilador IDL crea clases auxiliares _forany: ■ typedef short matriz[30]; // IDL typedef short vector[18]; // IDL Se genera en C++: typedef CORBA::Short matriz[30]; // C++ typedef CORBA::Short vector[18]; class matriz_forany { ... }; class vector_forany{ ... }; Se genera en C++: void operator <<= (CORBA::Any &, const Fecha &); void operator <<= (CORBA::Any &, Fecha *); CORBA::Boolean operator >>= (const CORBA::Any &, Fecha * &); Ejemplo de uso: ■ CORBA::Any a; // Se crea un Any vacío matriz x = ...; vector z = ...; a <<= matriz_forany(x); // Copia profunda a <<= vector_forany(z); // Copia profunda vector_fornay h; if(! (a >>= h) ) // Retorna true porque es del tipo correcto. Any sigue poseyendo h. cout << “Error”; Ejemplo de uso: ■ CORBA::Any a; // Se crea un Any vacío Fecha f = {29, “Marzo”}; a <<= f; // Copia profunda Fecha *g = new Fecha; a <<= g; // Copia superficial. Any toma propiedad. No debe hacerse delete g; AGB 13 Mapeo del tipo any en C++ CORBA::Any a; ■ // Se crea un Any vacío Para insertar y extraer otro Any: CORBA::Any externo, interno; // Se crean dos Any vacíos interno <<= (CORBA::Short)45; externo <<= interno; Banco_var banco1 = ...; // Se obtiene una referencia a Banco a <<= banco1; // Copia profunda Banco_ptr banco2; a >>= banco2; // Nunca usar _var para extraer (liberaría memoria 2 veces) CORBA::Any *otro; externo >>= otro; CORBA::Short x; *otro >>= x; Banco_ptr banco3 = ...; // Se obtiene una referencia a Banco a <<= banco3; // Copia profunda CORBA::release(banco3); Banco_ptr banco4 = ...; a <<= &banco4; 14 Mapeo del tipo any en C++ Para insertar y extraer referencias, se puede hacer de dos formas: ■ AGB // Se obtiene una referencia a Banco // Any toma propiedad y quizás libere banco4 (OJO: no debe // volver a usarse banco4); CORBA::Object_var obj; a >>= CORBA::Any::to_object(obj); // extracción como Object genérico Banco_var banco5 = Banco::_narrow(obj); // downcasting AGB 15 El tipo any ■ ➨ AGB 16 Códigos de tipos (TypeCode) Mapeo del tipo any en C++ Códigos de tipos (TypeCode) ■ TypeCode es un pseudo-objeto compuesto por un par de valores: TypeCode module CORBA TCKind { enum TCKind Descripción { tk_null, tk_void, tk_short, tk_long, tk_ushort, tk_ulong, tk_float, tk_double, tk_boolean, tk_char, tk_octect, tk_any, tk_TypeCode, tk_principal, tk_objref, tk_struct, tk_union, tk_enum, tk_string, tk_sequence, tk_array, tk_alias, tk_except, tk_longlong, tk_ulonglong, tk_longdouble, tk_wchar, tk_wstring, tk_fixed }; interface TypeCode // PIDL { TCKind kind(); // ... } AGB 17 } AGB 18 Códigos de tipos (TypeCode) ■ El valor “descripción” incluye cero o mas parámetros, dependiendo del valor TCKind: TCKind tk_fixed tk_objref tk_struct tk_union tk_enum tk_string tk_wstring tk_sequence tk_array tk_alias tk_except Parámetros Dígitos, escala ID del Depósito, nombre de la interfase nombre estructura, {nombre miembro, TypeCode miembro}..., ID depósito nombre unión, TypeCode discriminador, {etiqueta, nombre miembro, TypeCode miembro}..., ID depósito nombre enumeración, { nombre etiqueta} ..., ID depósito Tamaño máximo Tamaño máximo TypeCode elementos, tamaño máximo TypeCode elementos, dimensión nombre alias, TypeCode alias, ID depósito nombre excepción, { nombre miembro, TypeCode miembro}..., ID depósito AGB 19