2010-06-22 7 views
16

J'essaie d'exporter une variable globale à partir d'une DLL.Exportation de variables globales à partir de la DLL

.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; 

Lorsque je compile le code ci-dessus, Visual Studio se plaint:

foo.cpp (3): erreur C2370: ' foo ': redéfinition; différentes classes de stockage 1> foo.h (14): voir la déclaration de 'foo'

Si j'utilise:

external const Foo foo; 

dans .h le compilateur est heureux, mais la DLL n'exporte pas la symbole. J'ai réussi à exporter des fonctions avec des problèmes, mais les variables ne semblent pas fonctionner de la même manière ... Des idées?

+1

Pourquoi -1? S'il vous plaît justifier votre downvote. – Gili

Répondre

24

Dans votre tête:

API extern const Foo foo; 

Dans votre fichier source:

API const Foo foo; 

Si vous n'avez pas le mot-clé extern, votre compilateur C suppose que vous signifie pour déclarer une variable locale. (Il ne tient pas à ce que vous ayez inclus la définition dans un fichier d'en-tête.) Vous devez également indiquer au compilateur que vous envisagez d'exporter la variable lorsque vous la déclarez réellement dans votre fichier source.

+0

C'est ce qu'il a fait. Je vous remercie! – Gili

+0

S'il vous plaît, corrigez-moi si je me trompe. Utiliser __declspec (dllexport) avec le compilateur C (gcc de MINGW) ajoutera automatiquement le mot clé "extern" pour les variables, alors que le compilateur C++ (g ++ de MINGW) n'est pas le cas et vous utilisez explicitement "extern". – meolic

0

La classe Foo aura très probablement des fonctions membres en réalité, appeler celles d'un autre module provoquerait des erreurs de liaison avec la réponse OP/acceptée. La classe doit être définie comme dll export/import afin d'utiliser l'instance exportée en dehors de ce module pour éliminer les erreurs de liaison.

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

Cela dit, il pourrait mieux renommer #define API avec quelque chose comme dllexport il est donc logique pour les API et la classe d'exportation.