Chtoucas
Chtoucas

Reputation: 171

unresolved external symbol for __declspec(dllimport) when using dll to export class

I want to define a derived class based on a dll exported class. The base class is defined in Project A, and the derived class is in Project B.

Firstly, in Project A, preprocessor MYDLL_BUILD is defined. And I use a header file to specify export/import:

    #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

Then I define the base class:

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

In Project B, the preprocessor MYDLL_BUILD is not defined. Here is the derived class:

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

I have included the dll and lib file, but still I get the unresolved external symbol error:

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

I searched online, most of the answers claim that the lib is missing. But those instructions do not solve my problem.

When I change

    class MYDLL_API DllObject

to

    class __declspec(dllexport) DllObject 

The solution compiles with no error. I really do not understand the reason. Can someone please help? Thanks in advance.

Upvotes: 17

Views: 54662

Answers (2)

Omkar Patil
Omkar Patil

Reputation: 53

I had the same issue today. I was including the .dll and .lib files from my version of DllObject, But it wasn't helping.

To fix, What I had to do was add the .lib files name to my MyCLass version's project's Properties->Linker->Input->Additional dependencies.

If this doesn't work, You might want to add the .lib location's directory address in Properties->Linker->General->Additional library directories.

Upvotes: 2

Tomek Szpakowicz
Tomek Szpakowicz

Reputation: 14502

The reason is inlining.

In short, to make inline functions possible C++ must allow the same definition of function to be included and compiled in multiple compilation units (basically .cpp files) without causing errors. Compiler can, but doesn't have to emit code for any of this definitions. Then linker is allowed to chose one copy.

This complicates dll creation because you need to export exactly one copy but compiler doesn't know which copy is the right one. In this case by adding some code to DllObject.cpp you made the compiler emit code for DllObject and linker had some copy of DllObject::~DllObject to export.

I cannot give you more detailed explanation of your particular case because I don't know full source and compilation options for your project.

Upvotes: 8

Related Questions