Bueno, este problema es clásico, MS versus resto del mundo. Ya antes me ha ocurrido haciendo páginas web, tener que preocuparse de Internet Explorer y el resto de navegadores.
Mientras intentaba compilar GDT en Visual C++ 2005 Express, me encontré con un problema muy extraño.
Finalmente logre arreglar partes del código para que no me arrojara warnings en tiempo de compilación.
Pero en tiempo de enlazado (en el linker o vínculador) me daba mensajes raros cuando intentaba enlazar un programa de ejemplo con la librería.
El mensaje exactamente símbolo externo «símbolo» sin resolver. Ese símbolo podía ser una variable, una función, una clase, una una propiedad un método, etc…
El problema se produce porque en VC++ se deben exportar los métodos que se tomarán como «visibles» fuera de la librería dinámica (los métodos a los que el programa que se enlaza con ella tendrá acceso).
Según este tutorial de MSDN, la solución pasa por añadir __declspec(dllexport) antes de cada símbolo que se desea exportar a la DLL. El problema es que yo quiero que mi código sea multiplataforma, y esa sentencia claramente no me la va a tomar un compilador como GCC.
Esta es mi solución:
Me acordé de los #define y el pre-procesador. Antes de compilar, el pre-procesador hace reemplazos de trozos de código para que el compilador los entienda como una sola cosa. Entonces se puede hacer una parte condicional con #if/#ifdef…#endif para definir una constante que en tiempo de pre-procesado reemplace por __declspec(dllexport) si estamos compilando en VC++ o por nada si usamos otros compiladores.
Como estoy arreglando el código de GDT, use el nombre del proyecto para nombrar las constantes, se pueden cambiar a gusto
- Primero, se agregar al header (mi_modulo_de_libreria.h) de las clases antes de declarar la clase:
// HACK PARA COMPILAR EN VISUAL C++ 2005
#ifndef _GDT_EXPORT_
#ifdef _GDT_VC_STUDIO_2005_
#define _GDT_EXPORT_ __declspec(dllexport)
#else
#define _GDT_EXPORT_
#endif
#endif - Luego, antes de cada método declarado, se agregar _GDT_EXPORT_ así:
_GDT_EXPORT_ void mi_metodo1(void);
static _GDT_EXPORT_ void mi_metodo2(int, bool, char); - Luego, se configura el proyecto de librería agregando la definición _GDT_VC_STUDIO_2005_
- También se debe agregar a cualquier proyecto que enlace con la librería.
- No hace falta hacer nada más con los módulos .cpp de la librería, más que obviamente incluir su correspondiente cabecera:
#include «mi_modulo_de_libreria.h»
Listo, ahora podemos compilar el DLL y hacer programas que enlacen con la librería , y además no afectar el código en otros compiladores.
Advertencia 1: Este código tal cual está escrito no asume ninguna convención especifica para nombrar las constantes. Simplemente se me ocurrieron. Ocupe usted los nombres que le parezcan convenientes.
Adevetencia 2: Probablemente se pueda omitir el paso de agregar _GDT_VC_STUDIO_2005_ como definición en el compilador, ya que a veces pueden haber constantes internas del copilador que de inmediato sirven para identificar el compilador y plataforma, pero no conozco si exsiten en Visual C++ 2005 Express, y de existir, no se como se llaman. Pero al menos así funciona.