J'ai un DLL qui contient une classe avec statique --Membres. J'utilise __declspec(dllexport)
Afin de faire appel à cette classe Méthodes. Mais lorsque je le lie à un autre projet et essayez de le compiler, je reçois des erreurs "symboliques externes non résolues" pour les données statiques.
par exemple. Dans dll, test.h
class __declspec(dllexport) Test{
protected:
static int d;
public:
static void m(){int x = a;}
}
Dans dll, test.cpp
#include "Test.h"
int Test::d;
Dans l'application qui utilise le test, j'appelle m ().
J'ai également essayé d'utiliser __declSpec (dllexport) pour chaque méthode séparément, mais je reçois toujours les mêmes erreurs de liaison pour les membres statiques.
Si je vérifie le DLL (le .lib) à l'aide de Dumbin, je pouvais voir que les symboles ont été exportés.
Par exemple, l'application donne l'erreur suivante au moment de la liaison:
1>Main.obj : error LNK2001: unresolved external symbol "protected: static int CalcEngine::i_MatrixRow" (?i_MatrixRow@CalcEngine@@1HA)
Mais le déversement du .lib contient:
Version : 0
Machine : 14C (x86)
TimeDateStamp: 4BA3611A Fri Mar 19 17:03:46 2010
SizeOfData : 0000002C
DLL name : CalcEngine.dll
Symbol name : ?i_MatrixRow@CalcEngine@@1HA (protected: static int CalcEngine::i_MatrixRow)
Type : data
Name type : name
Hint : 31
Name : ?i_MatrixRow@CalcEngine@@1HA
Je ne peux pas comprendre comment résoudre ceci. Qu'est-ce que je fais mal? Comment puis-je passer sur ces erreurs?
P.s. Le code a été développé à l'origine pour Linux et la combinaison .SO/Binary Works sans problème
Edit: Dans le cas donné, les variables statiques ne sont pas directement référées par l'application, mais la méthode est inline car elle est dans l'en-tête. J'ai pu résoudre les erreurs de liaison en déplaçant les méthodes vers le fichier .cpp.
Dans this thread à cprogramming.com Il est suggéré qu'une variable statique est locale à la DLL et non exportée.
Le membre statique n'est pas accédé directement par code dans l'application appelante, uniquement via des fonctions membres de la classe dans la DLL. Cependant, il y a plusieurs fonctions en ligne accéder à l'élément statique. Ces fonctions seront alignées dans le code des applications appelantes apportant l'application appelante accéder directement au membre statique. Cela violera la constatation référencée ci-dessus que les variables statiques sont locales à la DLL et ne peuvent pas être référencées à partir de l'application d'appel.
Je suppose que la classe qui utilise le DLL doit voir dllimport au lieu de dllexport dans l'en-tête. Si je suis correct, cela peut Généralement être réalisé en définissant une macro de préprocesseur comme:
#ifdef EXPORTING
#define DECLSPEC __declspec(dllexport)
#else
#define DECLSPEC __declspec(dllimport)
#endif
puis utilisez-le dans la déclaration de classe:
class DECLSPEC Test{
protected:
static int d;
public:
static void m(){}
}
De sorte que dans le test.cpp (ou partout où il a du sens dans votre DLL==), vous pouvez spécifier que vous exportez de manière à être exporté avec Dllexport:
#define EXPORTING
#include "Test.h"
int Test::d;
alors que l'autre projet, qui ne définit pas l'exportation, verra Dllimport.
Est-ce que ça fait du sens?
Avec des dlls Windows, il existe une distinction spécifique entre __declspec(dllexport)
vs __declspec(dllimport)
, dllexport
_ doit être utilisé lors de la compilation de la DLL, dllimport
doit être utilisé lorsque Compilation de programmes liés à cette DLL. La manière standard de définir ce serait avec une macro.
Voici l'exemple Visual Studio:
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the DLL_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// DLL_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif