关于c ++:目标文件中未解析的外部符号

Unresolved external symbol in object files

在Visual Studio中进行编码时,发现一个未解决的外部符号错误我不知道该怎么办。我不知道怎么了。你能帮我破译一下吗?我应该在哪里查找哪种错误?

1
2
3
4
5
6
7
1>Form.obj : error LNK2019: unresolved external symbol"public: class Field * __thiscall Field::addField(class Field *)" (?addField@Field@@QAEPAV1@PAV1@@Z) referenced in function"public: void __thiscall Form::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse@Form@@QAEXAAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>Form.obj : error LNK2019: unresolved external symbol"public: virtual void __thiscall Field::parse(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?parse@Field@@UAEXAAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function"public: __thiscall InputField::InputField(class std::basic_stringstream<char,struct std::char_traits<char>,class std::allocator<char> > &)" (??0InputField@@QAE@AAV?$basic_stringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
1>Form.obj : error LNK2001: unresolved external symbol"public: virtual void __thiscall Field::prompt(void)" (?prompt@Field@@UAEXXZ)
1>Form.obj : error LNK2001: unresolved external symbol"public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getName(void)" (?getName@Field@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
1>Form.obj : error LNK2001: unresolved external symbol"public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall Field::getType(void)" (?getType@Field@@UAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ)
1>Form.obj : error LNK2001: unresolved external symbol"public: virtual void __thiscall Field::describe(void)" (?describe@Field@@UAEXXZ)
1>C:\Users\tomy\Documents\Visual Studio 2010\Projects\zapoctovkac++\Debug\zapoctovkac++.exe : fatal error LNK1120: 6 unresolved externals


此错误通常意味着某些函数有声明,但没有定义。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// A.hpp
class A
{
public:
  void myFunc(); // Function declaration
};

// A.cpp

// Function definition
void A::myFunc()
{
  // do stuff
}

在您的情况下,找不到定义。问题可能是您包含了一个头文件,它引入了一些函数声明,但是您可以:

  • 不要在cpp文件中定义函数(如果您自己编写了此代码)
  • 不包括包含定义的lib/dll文件
  • 一个常见的错误是,您将函数定义为独立函数,而忽略了.cpp文件中的类选择器,例如A::

    错:void myFunc() { /* do stuff */ }。右:void A::myFunc() { /* do stuff */ }


    检查是否包含解决方案中要引用的所有源文件。

    如果您没有将类Field的源文件(以及实现)包含在您的项目中,那么它将不会被构建,并且在编译期间您将无法链接。

    或者,您可能正在使用静态或动态库,忘记告诉链接器有关.lib的信息?


    它看起来缺少一个库或包含,您可以尝试找出您的库中哪些类具有getname、gettype等…并将其放入头文件或使用#include

    另外,如果这些恰好来自外部库,请确保在项目文件中引用它们。例如,如果此类属于abc.lib,则在Visual Studio中

  • 单击项目属性。
  • 转到配置属性,C/C++,生成,验证是否指向"附加"下的abc.lib位置包括目录。在"链接器"下输入,确保其他依赖项下的abc.lib。

  • 我刚刚看到一个问题,我不能从.cpp文件中的main调用函数,该文件在.h文件中正确声明,在.c文件中定义。遇到链接器错误。同时,我可以从通常的.c文件调用函数。这可能取决于通话约定。解决方案是在每个.h文件中添加以下预处理行:

    1
    2
    3
    4
    #ifdef __cplusplus
    extern"C"
    {
    #endif

    最后这些

    1
    2
    3
    #ifdef __cplusplus
    }
    #endif


    我的项目编译为x64项目时出错。我使用了一个编译为x86的库。

    我将库重新编译为x64,它解决了这个问题。


    我有同样的链接错误,但来自一个引用另一个dll的测试项目。发现在错误消息中指定的每个函数前面加上_declspec(dllexport)后,链路工作正常。


    我相信关于原因和补救措施的大部分要点已经被这个主题中的所有贡献者所涵盖。我只想指出我的"未解决的外部"问题,它是由一个定义为宏的数据类型引起的,该宏的替换方式与预期的不同,这会导致向相关函数提供不正确的类型,而且由于从未定义具有类型的函数,因此无法解决它。特别是,在C/C++ +>语言下,有一种称为"对待WCHARGT"的属性,它应该被定义为"否(/ZC:WCHARYT-)",但在我的情况下却没有。


    有时,如果添加了一个新的头文件,并且由于这个错误开始出现,那么您还需要添加库来除去unresolved external symbol

    例如:

    1
    #include WtsApi32.h

    需要:

    1
    #pragma comment(lib,"Wtsapi32.lib")

    确保用装饰头文件

    1
    2
    3
    4
    5
    6
    #ifndef YOUR_HEADER_H
    #define YOUR_HEADER_H

    // your header code here

    #endif

    如果你不这样做的话,坏的事情——包括这个——可能会发生。


    除了上面Chris Morris给出的极好的答案之外,我发现了一种非常有趣的方法,如果您调用的虚拟方法没有设置为pure,但是没有自己的实现,那么您也可以收到同样的错误。这是完全相同的原因(编译器找不到方法的实现,因此会出错),但我的IDE一点也没有发现这个错误。

    例如,以下代码将得到一个编译错误,并显示相同的错误消息:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    //code testing an interface
    class test
    {
       void myFunc();
    }

    //define an interface
    class IamInterface
    {
        virtual void myFunc();
    }

    //implementation of the interface
    class IamConcreteImpl
    {
        void myFunc()
        {
           1+1=2;
        }
    }

    但是,将iaminterface myfunc()更改为纯虚拟方法(必须实现的方法,而不是可以重写的虚拟方法)将消除编译错误。

    1
    2
    3
    4
    5
    //define an interface
    class IamInterface
    {
        virtual void myFunc() = 0;
    }

    希望这能帮助下一个stackoverflow的人逐步通过代码!


    链接器错误的一个可能原因也可以是inline函数,这些函数被声明但没有在随后包含在其他地方的头文件中定义。内联函数必须在其使用的每个翻译单元中定义。


    请参阅msdn上的链接器工具错误lnk2019,它有导致lnk2019的常见问题的详细列表。


    我在长时间内第一次做C++,当我忘记为函数定义添加CordNe::前缀时,我得到了这个错误,因为这对C++来说有点独特。所以记住也要检查一下!


    我只是很难接受。一切都是合乎逻辑的。我声明了一个构造函数,但没有定义它

    1
    2
    3
    4
    class SomeClass
    {
       SomeClass();  // needs the SomeClass::SomeClass(){} function defined somewhere, even here
    }

    当我忘了一些非常基本的东西时,我差点撞到键盘上。


    只是花了几个小时才发现问题出在我的主文件上,扩展名是.c,而不是.cpp

    :/


    我的问题是:我必须对其ctor为"未解决外部"的类进行转发声明。

    在我得到错误的文件中,我必须放置如下内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include"ClassB"

    class ClassB; // this solved the problem

    class ClassA{
        void foo(){
            ClassB* tmp = new ClassB();
            // ...
        }
    };

    当然,我的项目要复杂得多,这只是一个小例子。另外,在使用名称空间时,也要声明它们。


    在我的案例中是什么引起的:

    我有一个巨大的文件Foo.cpp没有foo.h.Foo.cpp开始如下:

    1
    2
    3
    4
    // ... 100 LOC here ...
    namespace NS {
    // ... 100 more LOC here ...
    static int var;

    我删除了"static"关键字,并添加了一个Foo.h

    1
    extern int var;

    你看到错误了吗?

    我完全错过了var最初是在名称空间中定义的,因为名称空间声明被隐藏在其他代码中。修复方法是这样更改外部:

    1
    2
    3
    namespace NS {
         extern int var;
    }

    还有一种可能要检查,这次是我的问题。

    我已经将函数添加到库中,并在搜索路径中包含了库的输出文件夹。

    但是我也有一个文件夹,上面列出了旧版本的库,所以vs使用的是旧库,当然没有找到新的函数。


    指针

    我有这个问题,用指针解决了它。我知道这不是你的问题,但我想我会提到它,因为我真希望一小时前我看到它时它就在这里。我的问题是声明一个静态成员变量而不定义它(定义需要在其他设置之后出现),当然指针不需要定义。同样的基本错误:P


    还有一个可能的问题(我只是挠头了一会儿):

    如果您将函数定义为inline,那么它们当然是这样!-必须在头(或内联文件)中定义,而不是在cpp中定义。在我的例子中,它们在一个内联文件中,但仅仅是因为它们是一个特定于平台的实现,而cpp包含了这个对应的inl文件…而不是头文件。是的,S*T发生了。

    我想我也会把这个放在这里,也许有人碰到了同样的问题,在这里找到了它。


    确保您没有试图将插入或提取运算符作为内联函数重载。我有这个问题,只有当我删除那个关键字时它才消失。


    我的问题是sconscript中没有定义cpp文件。这可能非常令人困惑,因为Visual Studio在项目中有cpp文件,但其他一些文件正在生成。