2010-06-22 17 views
16

Estoy intentando exportar una variable global desde una DLL.Exportación de variables globales desde DLL

foo.h

class Foo 
{ 
public: 
    Foo() 
    {} 
}; 

#ifdef PROJECT_EXPORTS 
    #define API __declspec(dllexport) 
#else 
    #define API __declspec(dllimport) 
#endif 

API const Foo foo; 

foo.cpp

#include "Foo.h" 

const Foo foo; 

Cuando puedo compilar el código anterior, Visual Studio se queja:

foo.cpp (3): error C2370: ' foo ': redefinición; diferentes clases de almacenamiento 1> foo.h (14): véase la declaración de 'foo'

Si utilizo:

external const Foo foo; 

en foo.h el compilador es feliz, pero entonces el archivo DLL no exporta la símbolo. Logré exportar funciones con problemas, pero las variables no parecen funcionar de la misma manera ... ¿Alguna idea?

+1

¿Por qué? Por favor, justifique su downvote. – Gili

Respuesta

24

En su cabecera:

API extern const Foo foo; 

En el archivo de origen:

API const Foo foo; 

Si usted no tiene la palabra clave extern, su compilador C supone que significa declarar una variable local. (No importa que hayas incluido la definición de un archivo de encabezado). También debes decirle al compilador que estás planeando exportar la variable cuando realmente la declaras en tu archivo fuente.

+0

Eso lo hizo. ¡Gracias! – Gili

+0

Por favor, corrígeme si me equivoco. El uso de __declspec (dllexport) con el compilador C (gcc de MINGW) automáticamente agregará la palabra clave "extern" para las variables, mientras usa el compilador C++ (g ++ de MINGW), este no es el caso y usted ha usado explícitamente "extern". – meolic

0

La clase Foo muy probablemente tendrá funciones miembro en realidad, llamar a las de otro módulo causaría errores del enlazador con la OP/respuesta aceptada. La clase debe definirse también como exportación/importación dll para utilizar la instancia exportada fuera de este módulo para eliminar los errores de enlace.

class API Foo 
{ 
public: 
    Foo() 
    {} 
    void DoSomeWork(); // calling this would cause link error if Foo is not defined as import/export class 
}; 

Dicho esto, podría cambiar el nombre de una mejor #define API con algo como dllexport así que tiene sentido para ambas API y la clase de exportación.