2009-07-07 9 views
5

Así que el común (al menos VS 2005 estados) forma de definir las exportaciones/importaciones para un archivo DLL es:Header File mismo para ambos DLL y biblioteca estática

#ifdef MY_EXPORTS 
#define MY_API __declspec(dllexport) 
#else 
#define MY_API __declspec(dllimport) 
#endif 

class MY_API MyClass { 
    ... 
}; 

Esto funciona muy bien si sólo estoy construyendo mi código como una DLL. Sin embargo, quiero tener la opción de usar una biblioteca estática O una DLL. Ahora, una solución obvia (pero terrible) es copiar todo el código, eliminando el DLL que define 'MY_API'. Ahora, lo que parecería un enfoque mucho mejor es un cambio de línea de comando para definir o no definir el material de la DLL. Sin embargo, en el caso de una biblioteca estática, ¿qué debería ser 'MY_API'?

#ifdef DLL_CONFIG 
    #ifdef MY_EXPORTS 
    #define MY_API __declspec(dllexport) 
    #else 
    #define MY_API __declspec(dllimport) 
    #endif 
#else 
    #define MY_API // What goes here? 
#endif 

class MY_API MyClass { 
    ... 
}; 

Ahora suponiendo que esto se puede hacer habrá problemas cuando un usuario de la biblioteca incluye los archivos de cabecera (es decir. Se tienen que definir 'DLL_CONFIG')?

Respuesta

12

Nada.

Déjalo como #define MY_API y todas las instancias de MY_API simplemente desaparecerán.

Puede agregar nuevas configuraciones de compilación, como Debug - DLL y Release - DLL que imitan a las demás excepto #define DLL_CONFIG.

Para clonar una configuración, vaya al administrador de configuración (como el menú desplegable del cuadro de lista Depuración/Liberación), luego en 'Configuración de solución activa' seleccione nueva. Ahora puede ponerle el nombre "Debug - DLL" y establecer Copy Settings en Debug y ahora lo que queda por hacer es definir DLL_CONFIG.

Para hacer esto, vaya a propiedades del proyecto-> propiedades de configuración-> C/C++ -> Preprocesador, y escriba DLL_CONFIG allí. También verá que se definen cosas como NDEBUG y WIN32.

Como haffax said, utilice nombres específicos del proyecto. Yo recomendaría algo así como:

#ifdef THEPROJECT_USE_DLL 
    #ifdef THEPROJECT_BUILDING_PROJECT 
     #define THEPROJECT_API __declspec(dllexport) 
    #else 
     #define THEPROJECT_API __declspec(dllimport) 
    #endif 
#else 
    #define THEPROJECT_API 
#endif 

Ahora los usuarios de su DLL simplemente #define THEPROJECT_USE_DLL si están utilizando la versión de DLL, al igual que su "-" DLL tienen configuraciones.

3

Simplemente defina MY_API como vacío. De esta manera:

#ifdef DLL_CONFIG 
    #ifdef MY_EXPORTS 
    #define MY_API __declspec(dllexport) 
    #else 
    #define MY_API __declspec(dllimport) 
    #endif 
#else 
    #define MY_API 
#endif 

En caso de enlace estático no es necesario declspec.

Los usuarios de su biblioteca tendrán que definir DLL_CONFIG si desean usarlo como dll o no definirlo si quieren usarlo como biblioteca estática. No habrá ningún problema. Este tipo de configuración se realiza en muchas bibliotecas.

Editar: Por supuesto, no debe utilizar los nombres MY_EXPORTS y DLL_CONFIG como tales. Utilice los prefijos específicos del proyecto para todas sus macros, para que no haya conflictos de nombres.

1

No hacer nada. No se necesita una convención de llamadas especiales para enlazar con una biblioteca estática. Lo único que debe hacer es asegurarse de que el vinculador se vincula con su.lib.

Cuestiones relacionadas