Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 718
Chtoucas Avatar asked Mar 17 '12 04:03

Chtoucas


People also ask

What does __ Declspec Dllimport mean?

__declspec(dllimport) is a storage-class specifier that tells the compiler that a function or object or data type is defined in an external DLL. The function or object or data type is exported from a DLL with a corresponding __declspec(dllexport) .

Is __ Declspec Dllimport necessary?

Using __declspec(dllimport) is optional on function declarations, but the compiler produces more efficient code if you use this keyword. However, you must use __declspec(dllimport) for the importing executable to access the DLL's public data symbols and objects.

How do I fix unresolved external symbol lnk2001?

To fix this issue, add the /NOENTRY option to the link command. This error can occur if you use incorrect /SUBSYSTEM or /ENTRY settings in your project. For example, if you write a console application and specify /SUBSYSTEM:WINDOWS, an unresolved external error is generated for WinMain .


1 Answers

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.

like image 94
Tomek Szpakowicz Avatar answered Sep 28 '22 11:09

Tomek Szpakowicz