目标文件中未解析的外部符号


180

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

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

26
未解析的符号是您已在某处声明但从未定义的符号。通常,这意味着您已经#include了一些第三方库的头文件,但没有告诉链接器在哪里可以找到该库的相应.obj文件。
deong 2012年

7
一个很常见的错误是,您将一个函数定义为独立函数,而忘记了.cpp文件中的类选择器: 您执行此操作(错误): void myFunc() { /* do stuff */ } 而不是此操作(正确): void A::myFunc() { /* do stuff */ }
jave.web

如果不想在.cpp文件中进一步定义括号,也可以直接在文件中添加括号,如下所示:void myFunc() {};
Patapoom

Answers:


302

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

例:

// A.hpp
class A
{
public:
  void myFunc(); // Function declaration
};

// A.cpp

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

在您的情况下,找不到定义。问题可能是您包括一个头文件,该头文件带来了一些函数声明,但是您要么:

  1. 不要在cpp文件中定义函数(如果您自己编写了此代码)
  2. 不包括包含定义的lib / dll文件

一个常见的错误是您将函数定义为独立函数,而忘记了类选择器,例如A::,在.cpp文件中:

错误: void myFunc() { /* do stuff */ }
正确: void A::myFunc() { /* do stuff */ }


2
如何在我的项目中包含所说的lib文件?
tmj 2014年

@tMJ这取决于您使用的环境。我会在网上或在此站点上查找教程。
克里斯·莫里斯

@ChrisMorris该函数的定义不可用,不是因为我没有正确链接它或其他东西。但是,由于该dll不在内存中,因此必须通过LoadLibrary调用进行加载。(FTR)
tmj

2
最后的建议正是这里的问题。我void myFunc() {}不是在做A::void myFunc() {}
查尔斯(Charles)

辉煌的答案。从其他位置复制方法后,我实际上忘记了(1)和A ::部分。
RoG

24

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

如果您的项目中没有包含该类的源文件(以及实现),Field则不会生成该类,并且在编译过程中将无法链接。

另外,也许您使用的是静态库或动态库,却忘记了告诉链接程序有关.libs的信息?


3
引用正确的lib文件可以解决此问题。使用项目->属性->链接器->常规->其他库目录和项目->属性->链接器->输入->其他依赖关系来引用lib目录和lib文件
zak

11

它似乎缺少库或包含库,您可以尝试找出库中具有getName,getType等...的类,并将其放在头文件中或使用#include

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

  1. 单击项目属性。
  2. 转到“配置属性”,“ C / C ++”,“生成”,确认您指向“其他包含目录”下的abc.lib位置。在“链接器”下的“输入”下,确保“其他依赖项”下有abc.lib。

9

我刚刚看到了无法从.cpp文件中的main调用函数,在.h文件中正确声明并在.c文件中定义的问题。遇到链接器错误。同时,我可以从通常的.c文件中调用函数。可能取决于呼叫约定。解决方案是在每个.h文件中添加以下行数:

#ifdef __cplusplus
extern "C"
{
#endif

最后这些

#ifdef __cplusplus
}
#endif

7

我的项目被编译为x64项目时出现错误。并且我使用了一个编译为x86

我将库重新编译为x64,并解决了该问题。


5

有时,如果添加了新的头文件,并且由于该错误而开始出现此错误,则还需要添加库以摆脱unresolved external symbol

例如:

#include WtsApi32.h

将需要:

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

4

我有相同的链接错误,但是来自一个引用另一个dll的测试项目。发现_declspec(dllexport)在错误消息中指定的每个功能之前添加 了链接之后,链接运行良好。


3

我相信本主题中的所有贡献者都涵盖了有关原因和补救措施的大多数要点。我只是想指出我的“未解决的外部”问题,它是由定义为宏的数据类型引起的,该数据类型的替换方式与预期的不同,这导致向该函数提供了错误的类型,并且由于该函数的类型为从未定义过,无法解决。特别地,在C / C ++->语言下,有一个名为“ Treat WChar_t As Built in Type”的属性,应该将其定义为“ No(/ Zc:wchar_t-)”,但在我的情况下没有。


谢谢,这会导致我的设置出现问题(“否(/ Zc:wchar_t-)”)
Noypi Gilas

2

除了上面的Chris Morris的出色回答之外,我发现了一种非常有趣的方式,如果您要调用的虚拟方法尚未设置为纯方法,但该方法不是其自己的实现,则可以收到相同的错误。这是完全相同的原因(编译器找不到该方法的实现,因此很糟),但是我的IDE至少没有捕获到此错误。

例如,以下代码将获得带有相同错误消息的编译错误:

//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()更改为纯虚拟方法(“必须”实现的方法,而不是“可以”重写的虚拟方法)将消除编译错误。

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

希望这有助于下一个StackOverFlow人员逐步执行代码!



2

确保使用以下命令装饰头文件

#ifndef YOUR_HEADER_H
#define YOUR_HEADER_H

// your header code here

#endif

如果您不这样做,可能会发生坏事-包括此事


8
使用#pragma once怎么样?
艾伦·利纳托茨2015年

2

另一个可能的问题(我只是挠了一下头):

如果将函数定义为inline,则它们(当然!)必须在标头(或内联文件)中而不是cpp中定义
就我而言,它们位于一个内联文件中,但这仅是因为它们是特定于平台的实现,并且cpp包含了该对应的inl文件…而不是标头。是的,这不会发生。

我以为我也会把它留在这里,也许其他人遇到了同样的问题并在这里找到了。


1
对于对此表示反对的人:至少要留下评论,为什么您认为答案是错误的或没有帮助。没有评论的不赞成投票最多毫无价值。
约翰·斯塔丹斯基

1

我对此很难受。一切都在逻辑上进行了设置。我声明了一个构造函数,但是没有定义它

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

当我忘了这么简单的东西时,我几乎敲了敲键盘。


1

我很长时间以来第一次在做一些C ++,但是当我忘记为函数定义添加ClassName ::前缀时,却遇到了这个错误,因为这对于C ++来说有点独特。因此,请记住也要检查!


1

导致此链接器错误的一个可能原因也可能inline是已声明但未在头文件中定义的函数,该头文件随后包含在其他位置。内联函数必须在使用它们的每个翻译单元中定义。


0

指针

我有这个问题,并通过使用指针解决了。我看到这不是您的问题,但我想提一提,因为我希望一个小时前看到它时已经在这里。我的问题是声明一个静态成员变量而不定义它(定义需要在其他设置之后进行),当然,指针不需要定义。同样的基本错误:P


3
这里有一个例子非常有用。
moffeltje

0

我的问题是sconscript中没有cpp定义文件。这可能非常令人困惑,因为Visual Studio cpp在项目中有文件,但其他东西正在完全构建。


0

我的问题是:我必须对ctor为“外部未解决”的类进行前向声明

在出现错误的文件中,我必须输入以下内容:

#include "ClassB" 

class ClassB; // this solved the problem

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

当然,我的项目要复杂得多,这只是一个片段示例。同样在使用名称空间时,也要声明它们


0

仅仅花了几个小时才发现问题是我的主文件具有扩展名.c而不是.cpp

:/


0

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

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

但是我还有一个文件夹,其中包含以前列出的较旧版本的库,因此VS使用的是旧库,当然找不到新功能。


0

确保您不尝试将插入或提取运算符作为内联函数重载。我遇到了这个问题,当我删除该关键字时它才消失。


0

在我的情况下是什么导致的:

Foo.cpp没有Foo.h,我的文件很大。Foo.cpp开始是这样的:

// ... 100 LOC here ...
namespace NS {
// ... 100 more LOC here ...
static int var;

我删除了“静态”关键字,并添加了一个Foo.h

extern int var;

你看到错误了吗?

我完全想念var最初是在名称空间中定义的,因为名称空间声明埋在其他代码中。解决方法是像这样更改外部元素:

namespace NS {
     extern int var;
}

0

函数调用约定是“未解析的外部符号”错误的可能原因。

确保所有源文件都使用相同的标准(.c或.cpp),或指定调用约定。

否则,如果一个文件是C文件(source.c),另一个文件是.cpp文件,并且它们链接到同一标头,则将引发“未解析的外部符号”错误,因为该函数首先被定义为C cdecl函数,但是使用相同标头的C ++文件将查找C ++函数。

为避免出现“未解决的外部符号错误”,请确保函数调用约定在使用它的文件之间保持相同。


0

在仔细研究链接器错误之前的几行之前,我来这里是寻找可能的解释。原来,这是一个缺少全局声明的附加可执行文件!


0

我刚刚有同样的错误,我管理通过更换,以避免它;{}在头文件。

#ifndef XYZ_h
#define XYZ_h
class XYZ
{
    public:
    void xyzMethod(){}
}
#endif

当时void xyzMethod();它不想编译。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.