ZeroC Ice: Desarrollo de plugins
Añadir nueva funcionalidad a ZeroC Ice es fácil: usando plugins. Ice provee una interfaz local, Ice::Plugin, que podemos usar para crearlos. Veamos un ejemplo sencillo. Probado en Ice 3.3.
Puesto que un plugin no es lo primero que se suele hacer al trabajar con Ice, deduzco que ya tienes experiencia, y que tienes Ice instalado correctamente, las herramientas de compilación necesarias, etc.
Interfaz
En primer lugar, veamos la interfaz que tenemos que implementar. En Debian, se encuentra en el fichero /usr/share/slice/Ice/Plugin.ice
module Ice { local interface Plugin { void initialize(); void destroy(); }; };
Sencilla, ¿verdad? Bien, pues lo primero que podemos hacer es implementar esos dos métodos. Como no es una interfaz RMI, no es necesario usar los translators, así que la implementación es directa. Veamos el código:
PluginI.h
PluginI.cpp
Por supuesto, puedes cambiar el nombre de la clase y el contenido… ;-) Como ves, tenemos dos métodos, initialize y destroy. Quizá te preguntes porqué no usar el constructor y el destructor. Sencillo: para resolver problemas de dependencias entre los plugins, Ice los carga todos en primero lugar y luego los inicializa. Así, si necesitas usar otro plugin, en el initialize sabes que ya estará cargado (pero puede no estar inicializado. Si necesitas un orden de carga determinado, puedes especificarlo en la configuración. Para más detalles, véase el manual).
Bien, ya tenemos el plugin propiamente dicho. El objeto puede implementar más métodos, y usando el PluginManager, puedes obtener una instancia para usarlo cuando lo necesites. Pero ¿cómo lo crea el PluginManager? Pues esa es nuestra siguiente tarea. Tenemos que definir una función que se encargue de instanciarlo, y que pueda ser llamada desde la factoría. He aquí una muestra:
Loader.cpp
Como ves, la definición debe ser en C, no en C++. Se recomienda en el manual usar la macro ICE_DECLSPEC_EXPORT para dotarlo de compatibilidad entre plataformas. Como es C, no tenemos smart pointer, por lo que retornamos un puntero. El nombre de la función puede ser cualquiera, pues luego debemos especificarlo en el fichero de configuración.
¡Y ya lo tenemos! Esta es la estructura mínima de un plugin (a mi entender). Vamos a probarlo con un ejemplo muy sencillo:
test.cpp
¡Andando! Pero… ¿donde se usa el plugin? Pues bien, en este ejemplo, que sólo pretende demostrar la carga y descarga del mismo, no se usa :-p Pero nos sirve igualmente. Si añadimos una línea en el fichero de configuración tal que así:
config
cargará nuestro plugin, y lo registrará en el PluginManager, disponible para que lo usemos cuando queramos (tip: el communicator tiene un método llamado getPluginManager…). El nombre del plugin, en este caso Sample, puedes elegirlo tu… :-d.
Compilando
Para que todo esto funcione, tienes que compilarlo :-p. El plugin debe ser una librería, para no tener que recompilar Ice cada vez que añadas uno. Los flags de compilación son los de siempre: -fPIC -shared. Un detalle a tener en cuenta es el nombre: debe terminar en .33, que es la versión de Ice para la que enlazas, así que tienes que crearte un enlace simbólico para enlazar correctamente… Para ayudarte a compilar el ejemplo, he te aquí un Makefile:
Makefile
En la sección de descargas tienes todo el código, listo para funcionar. Si lo compilas y lo lanzas, podrás ver algo como esto:
Y listo, ya tienes tu plugin funcionando. ¡Que te aproveche! Próxima parada, un endpoint… :-p
Referencias
Descargas
- Código del ejemplo: https://bitbucket.org/OscarAcena/ice.plugin-sample