Conversión sencilla de tipos CORBA

Tradicionalmente el mapping de C++ de CORBA es un auténtico suplicio para aquellos que lo tienen que usar. Con motivo de la finalización de mi tesis (que ya queda poco), y con nuevas técnicas y liberías de C++ que estudio, se me van ocurriendo ideas que hacen más sencilla la programación con CORBA.

Por ejemplo, tradicionalmente para convertir un objeto CORBA::Object a cualquier otro tipo, había que escribir unas cuantas líneas de código bastante tediosas, y no muy fáciles de factorizar por cómo es el mapping de CORBA. Por ejemplo, para obtener el POA raíz:


CORBA::Object_var o = orb->resolve_initial_references("RootPOA");
PortableServer::POA_var rootPOA = PortableServer::POA::_narrow(o.in());


Esto es, hay que crear un objeto de tipo CORBA::Object_var que gestiona la memoria dinámica automáticamente, de la función resolve_initial_references del ORB. A continuación hay que declarar una variable del tipo que queremos (PortableServer::POA_var) y convertir ese objeto con la función PortableServer::POA::_narrow(), de dentro del namespace PortableServer::POA. Este código se repite para cualquier tipo que queramos convertir desde Object, y como se ve, es difícil extraer una función template, por ejemplo, porque escribirla sería casi tan largo como escribir todo ese código.

Sin embargo, se me ha ocurrido que se puede sobrecargar el operador "<<", por ejemplo, de la siguiente forma:


PortableServer::POA_ptr operator<<(PortableServer::POA_var& poa, CORBA::Object_ptr o)
{
poa = PortableServer::POA::_narrow(o);
return poa.in();
}


Y así escribirlo de la forma más sencilla:


CORBA::Object_var o = orb->resolve_initial_references("RootPOA");
PortableServer::POA_var rootPOA;
rootPOA << o;


Podemos ir un paso más allá y hacer que el objeto CORBA se consuma automáticamente y no tengamos que hacer un objeto Object_var para guardar el valor temporal retornado por la llamada a resolve_initial_references, y la función de arriba quedaría como sigue:


PortableServer::POA_ptr operator<<(PortableServer::POA_var& poa, CORBA::Object_ptr o)
{
poa = PortableServer::POA::_narrow(o);
CORBA::release(o);
return poa.in();
}


Con este operador, el código de arriba quedaría como sigue:


PortableServer::POA_var rootPOA;
rootPOA << orb->resolve_initial_references("RootPOA");


Y no se perdería nada de memoria. Casi igual a cómo se hace en Java, donde no hay que preocuparse por la gestión de memoria. El único problema que habría es si cogemos un CORBA::Object_var previo, donde entonces a la hora de llamarla hay que tener la precaución de hacer lo siguiente:


CORBA::Object_var o = orb->resolve_initial_references("RootPOA");
PortableServer::POA_var rootPOA;
rootPOA << o._retn();


(esto es, llamar a _retn() del objeto para que olvide la gestión de memoria interna).

blog comments powered by Disqus