web-dev-qa-db-fra.com

symbole externe non résolu pour __declspec (dllimport) lors de l'utilisation de dll pour exporter la classe

Je veux définir une classe dérivée basée sur une classe exportée par DLL. La classe de base est définie dans le projet A et la classe dérivée est dans le projet B.

Tout d'abord, dans le projet A, le préprocesseur MYDLL_BUILD est défini. Et j'utilise un fichier d'en-tête pour spécifier l'exportation/importation:

    #if !defined(MYDLL_BUILD)
    #   pragma comment(lib, "myDll.lib")
    #endif

    #if defined(MYDLL_BUILD)
    #   define MYDLL_API __declspec(dllexport)
    #else
    #   define MYDLL_API __declspec(dllimport)
    #endif

Ensuite, je définis la classe de base:

class MYDLL_API DllObject
{
public:
    virtual ~DllObject() {}
protected:
    DllObject() { m_count = 3; }
private:
    int m_count;
};

Dans le projet B, le préprocesseur MYDLL_BUILD n'est pas défini. Voici la classe dérivée:

class MyClass : public DllObject
{
public:
    ~MyClass(){}
    MyClass() { m_data = 20; }
private:
    int m_data;
}; 

J'ai inclus le fichier dll et lib, mais j'obtiens toujours l'erreur de symbole externe non résolue:

2>Test_Entry.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall ADAI::DllObject::~DllObject(void)" (__imp_??1DllObject@ADAI@@UAE@XZ) referenced in function "public: virtual __thiscall MyClass::~MyClass(void)" (??1MyClass@@UAE@XZ)
2>Test_Entry.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) protected: __thiscall ADAI::DllObject::DllObject(void)" (__imp_??0DllObject@ADAI@@IAE@XZ) referenced in function "public: __thiscall MyClass::MyClass(void)" (??0MyClass@@QAE@XZ)
2>c:\Users\Adai\Documents\Visual Studio 2010\Projects\Test_Main\Debug\Test_Main.exe : fatal error LNK1120: 2 unresolved externals

J'ai cherché en ligne, la plupart des réponses affirment que la bibliothèque est manquante. Mais ces instructions ne résolvent pas mon problème.

Quand je change

    class MYDLL_API DllObject

à

    class __declspec(dllexport) DllObject 

La solution se compile sans erreur. Je ne comprends vraiment pas la raison. Puis-je avoir une aide s'il vous plait? Merci d'avance.

17
Chtoucas

La raison en est inline.

En bref, pour rendre les fonctions en ligne possibles, C++ doit permettre à la même définition de fonction d'être incluse et compilée dans plusieurs unités de compilation (essentiellement des fichiers .cpp) sans provoquer d'erreurs. Le compilateur peut, mais n'a pas à émettre de code pour aucune de ces définitions. L'éditeur de liens est alors autorisé à choisir une copie.

Cela complique la création de DLL car vous devez exporter exactement une copie mais le compilateur ne sait pas quelle copie est la bonne. Dans ce cas, en ajoutant du code à DllObject.cpp, vous avez fait en sorte que le compilateur émette du code pour DllObject et l'éditeur de liens avait une copie de DllObject::~DllObject exporter.

Je ne peux pas vous donner d'explication plus détaillée de votre cas particulier car je ne connais pas les options complètes de compilation et de source pour votre projet.

6
Tomek Szpakowicz