C++ 使用 dll 导出类时 __declspec(dllimport) 的未解析外部符号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9747207/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:15:22  来源:igfitidea点击:

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

c++visual-c++inlinedllimportdllexport

提问by Chtoucas

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.

我想定义一个基于 dll 导出类的派生类。基类在项目 A 中定义,派生类在项目 B 中。

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

首先,在项目A中,定义了预处理器MYDLL_BUILD。我使用头文件来指定导出/导入:

    #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:

在项目 B 中,未定义预处理器 MYDLL_BUILD。这是派生类:

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:

我已经包含了 dll 和 lib 文件,但仍然出现未解决的外部符号错误:

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.

我在网上搜索,大多数答案都声称缺少 lib。但是这些说明并不能解决我的问题。

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.

解决方案编译没有错误。我真的不明白原因。有人可以帮忙吗?提前致谢。

回答by Tomek Szpakowicz

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.

简而言之,要使内联函数成为可能,C++ 必须允许在多个编译单元(基本上是 .cpp 文件)中包含和编译相同的函数定义,而不会导致错误。编译器可以,但不必为这些定义中的任何一个发出代码。然后允许链接器选择一个副本。

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 DllObjectand linker had some copy of DllObject::~DllObjectto export.

这使 dll 创建变得复杂,因为您需要导出一个副本,但编译器不知道哪个副本是正确的。在这种情况下,通过向 DllObject.cpp 添加一些代码,您使编译器发出代码DllObject并且链接器有一些DllObject::~DllObject要导出的副本。

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

我无法对您的特定情况提供更详细的解释,因为我不知道您项目的完整源代码和编译选项。