¿Qué es __declspec y cuándo necesito usarlo?

157

He visto instancias __declspecen el código que estoy leyendo. ¿Qué es? ¿Y cuándo necesitaría usar esta construcción?

Scott J
fuente
1
Si no tuvo suerte y se mudó de Linux a Windows, podría perder el tiempo tratando de descubrir por qué sus archivos DLL no funcionarían, hasta que descubra que tiene que agregar __declspec(dllexport)antes de cada función en su biblioteca
SomethingSomething

Respuestas:

74

Esta es una extensión específica de Microsoft para el lenguaje C ++ que le permite atribuir un tipo o función con información de clase de almacenamiento.

Documentación

__declspec (C ++)

JaredPar
fuente
19
Gracias, pero ¿para qué lo usaría?
Scott J
44
Para declarar interfaces y clases COM, por ejemplo, usa __declspec (uuid), para exportar funciones sin un archivo DEF usa __declspec (dllexport), etc. La lista completa es bastante larga.
Seva Alekseyev
1
@ScottJ Lo uso constantemente para las propiedades: __declspec (propiedad (get = X put = X)) identificador de tipo de datos. MSDN tiene más detalles, por supuesto. Como "programador de C # a C / C ++" es una dicha!
MasterMastic
51

Los ejemplos canónicos son __declspec(dllimport)y __declspec(dllexport), que le indican al vinculador que importe y exporte (respectivamente) un símbolo desde o hacia un archivo DLL.

// header
__declspec(dllimport) void foo();


// code - this calls foo() somewhere in a DLL
foo();

( __declspec(..)solo envuelve las cosas específicas de Microsoft: para lograr la compatibilidad, uno generalmente lo envolvería con macros)

Alexander Gessler
fuente
8
@tetris, no lo sabes por el código. El vinculador toma la decisión y elegirá el primero .libque encuentre que tenga un símbolo exportado coincidente.
Euro Micelli el
19

Se utiliza principalmente para importar símbolos de / exportar símbolos a una biblioteca compartida (DLL). Tanto los compiladores de Visual C ++ como GCC son compatibles __declspec(dllimport)y __declspec(dllexport). Otros usos (algunos solo de Microsoft) están documentados en el MSDN .

AndiDog
fuente
12

Otro ejemplo para ilustrar la palabra clave __declspec :

Cuando está escribiendo un controlador de kernel de Windows, a veces desea escribir sus propias secuencias de código de prólogo / epílogo utilizando código de ensamblador en línea , para que pueda declarar su función con el atributo simple .

__declspec( naked ) int func( formal_parameters ) {}

O

#define Naked __declspec( naked )
Naked int func( formal_parameters ) {}

Consulte desnudo (C ++)

HackNone
fuente
8

Esencialmente, es la forma en que Microsoft presenta sus extensiones C ++ para que no entren en conflicto con futuras extensiones del estándar C ++. Con __declspec, puede atribuir una función o clase; el significado exacto varía según la naturaleza de __declspec. __declspec (desnudo), por ejemplo, suprime la generación de prólogo / epílogo (para manejadores de interrupciones, código incrustable, etc.), __declspec (hilo) hace un hilo local variable, y así sucesivamente.

La lista completa de los atributos __declspec está disponible en MSDN y varía según la versión y la plataforma del compilador.

Seva Alekseyev
fuente
1
Teniendo en cuenta los compiladores no son de Microsoft como GCC 4.2, oferta alternativa que además de su __attribute__ ((dllexport))a __declspec(dllexport), ¿es justo a la llamada __declspec, un Microsoft-única extensión?
user2338150
0

Sé que han pasado ocho años, pero quería compartir este código que se encuentra en MRuby que muestra cómo se __declspec()puede usar al mismo nivel que el export keyword.

/** Declare a public MRuby API function. */
#if defined(MRB_BUILD_AS_DLL)
#if defined(MRB_CORE) || defined(MRB_LIB)
# define MRB_API __declspec(dllexport)
#else
# define MRB_API __declspec(dllimport)
#endif
#else
# define MRB_API extern
#endif

fuente