C++ y C#: Enumeraciones compartidas

Acabo de leer en uno de los blogs a los que estoy suscrito un tema que considero bastante curioso e interesante, no porque sea una cosa que se vaya a utilizar todos los días (de hecho desaconsejo su uso), pero tiene su aplicación y su motivo.


El artículo se titula «Sharing enums across C# and C++», es decir, «Compartiendo enumeraciones entre C# y C++». Ojo, no C++/CLI, sino C++. El de toda la vida.


Para aquellos que no se aclaren mucho con el inglés, lo que básicamente hace el autor es explicar que a veces es necesario compartir código nativo con manejado, y que dicha compartición necesita de enumeraciones que son iguales en ambos lados. La solución obvia es mantener dos copias de la enumeración, pero eso resulta propenso a errores (lo más fácil es que se te olvide actualizar uno de los dos lados). Por ello, lo que comenta es crearte un fichero con la extensión .CS que contenga la citada enumeración e incluirla en la parte de C++, ya que el preprocesador de C++ no fuerza que los ficheros tengan ciertas extensiones en concreto. Si las tiene, él sabe cómo operar con ellas por defecto. Si no las tiene, pues para eso están las opciones de compilación, para decirle que un archivo con la extensión «.halakerollo» es un fichero de C++.


Extendiendo un poco más el tema, podríamos incluso hacernos un pre-preprocesador para que tomara un fichero fuente en C# y nos generara uno válido en C++, que es lo que hace, por ejemplo, la utilidad «MOC» de QT, que traduce el código generado por el diseñador visual a C++.


Y siempre te queda el uso de macros del preprocesador. Por ejemplo, supongamos que necesitamos una clase adaptadora muy sencilla:



ref class Adap
{
    static String ^Adapta
 (String ^cad){…}
};


Y que dicha clase ha de estar disponible y compartida entre C++/CLI y C++. ¿Cómo lo haríamos con un solo código fuente? Sencillo:



#ifndef __cplusplus_cli
    #define ref
    #define ^  *
    #define String std::string
#endif


 ref class Adap
{
    static String ^Adapta
 (String ^cad){…}
};


Y estaremos trabajando con strings .NET o strings STL según la clase esté compilada en C++/CLI o C++. Lo mismo puede hacerse con C# y C++/CLI ó C++, aunque en este caso debemos forzar que las definiciones estén del lado de C++ o de C++/CLI, ya que el preprocesador de C# es meramente testimonial.


[Nota: no he comprobado el ejempo, pero tiene que funcionar]

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *