链接器工具错误 LNK2001Linker Tools Error LNK2001

无法解析的外部符号"符号"unresolved external symbol "symbol"

已编译的代码可以引用或调用符号,但该符号并不定义中的任何库或链接器指定的对象文件。The compiled code makes a reference or call to symbol, but that symbol isn't defined in any of the libraries or object files specified to the linker.

此错误消息后跟错误LNK1120This error message is followed by fatal error LNK1120. 必须修复所有 LNK2001 和 LNK2019 错误,若要修复错误 LNK1120。You must fix all LNK2001 and LNK2019 errors to fix error LNK1120.

可能的原因Possible causes

有许多方法来获取此错误,但所有这些涉及对函数或变量的链接器不能引用解决,或查找的定义。There are many ways to get this error, but all of them involve a reference to a function or variable that the linker can't resolve, or find a definition for. 编译器可标识时某个符号未声明,但不是时它不是定义,因为可以在不同的源代码文件或库中的定义。The compiler can identify when a symbol is not declared, but not when it is not defined, because the definition may be in a different source file or library. 如果符号引用,但永远不会定义,链接器将生成错误。If a symbol is referred to but never defined, the linker generates an error.

编码问题Coding issues

此错误可能由不匹配的情况下,在你的源代码或模块定义 (.def) 文件。This error can be caused by mismatched case in your source code or module-definition (.def) file. 例如,如果为变量命名var1在一个 c + + 源文件,并尝试访问其作为VAR1中另一个,会生成此错误。For example, if you name a variable var1 in one C++ source file and try to access it as VAR1 in another, this error is generated. 若要解决此问题,使用一致地拼写和大小写的名称。To fix this issue, use consistently spelled and cased names.

可以使用的项目中导致此错误函数内联如果源代码文件中,而不是标头文件中定义的函数。This error can be caused in a project that uses function inlining if you define the functions in a source file rather than in a header file. 内联的函数无法查看外部定义它们的源代码文件。Inlined functions can't be seen outside the source file that defines them. 若要解决此问题,请在其中声明的标头中定义内联的函数。To fix this issue, define the inlined functions in the headers where they are declared.

如果不使用从 c + + 程序上调用 C 函数可以导致此错误extern "C"C 函数声明。This error can be caused if you call a C function from a C++ program without using an extern "C" declaration for the C function. 编译器针对 C 和 c + + 代码,使用不同的内部符号命名约定,它是当正在解析符号时,链接器查找 internal 符号名称。The compiler uses different internal symbol naming conventions for C and C++ code, and it is the internal symbol name that the linker looks for when resolving symbols. 若要解决此问题,请使用extern "C"C 函数在 c + + 代码,这会导致编译器使用这些符号 C 内部命名约定中使用的所有声明周围的包装器。To fix this issue, use an extern "C" wrapper around all declarations of C functions used in your C++ code, which causes the compiler to use the C internal naming convention for those symbols. 编译器选项/Tp/Tc会导致编译器文件分别编译为 c + + 或 C,而不考虑文件扩展名。Compiler options /Tp and /Tc cause the compiler to compile files as C++ or C, respectively, regardless of the filename extension. 这些选项可能会导致与您期望的不同内部函数名称。These options can cause internal function names different from what you expect.

尝试引用函数或不具有外部链接的数据可以导致此错误。This error can be caused by an attempt to reference functions or data that don't have external linkage. 在 c + + 内联函数和const数据具有内部链接,除非显式指定为externIn C++, inline functions and const data have internal linkage unless explicitly specified as extern. 若要解决此问题,请使用显式extern上符号的声明定义源文件外部引用。To fix this issue, use explicit extern declarations on symbols referred to outside the defining source file.

此错误可能引起缺少函数体或变量定义。This error can be caused by a missing function body or variable definition. 声明,但未定义,变量、 函数或类在代码中时,此错误很常见。This error is common when you declare, but don't define, variables, functions, or classes in your code. 编译器只需要一个函数原型或extern变量声明来生成没有错误,但链接器的对象文件无法解析对函数的调用或对该变量的引用,因为没有函数代码或变量空间保留。The compiler only needs a function prototype or extern variable declaration to generate an object file without error, but the linker cannot resolve a call to the function or a reference to the variable because there is no function code or variable space reserved. 若要解决此问题,请确保每个引用的函数和变量完全定义中的源文件或包含在链接中的库。To fix this issue, make sure that every referenced function and variable is fully defined in a source file or library included in your link.

使用返回值和参数类型或不匹配函数定义中的调用约定的函数调用可导致此错误。This error can be caused by a function call that uses return and parameter types or calling conventions that do not match those in the function definition. 在 c + + 对象文件中名称修饰合并到最终修饰的函数名称,用作符号以匹配时调用的调用约定、 类或命名空间范围和返回类型和参数类型的函数解决其他对象文件中的函数。In C++ object files, Name decoration incorporates the calling convention, class or namespace scope, and return and parameter types of a function into the final decorated function name, which is used as the symbol to match when calls to the function from other object files are resolved. 若要解决此问题,请确保声明、 定义和对所有函数的调用使用相同的作用域、 类型和调用约定。To fix this issue, make sure that the declaration, definition, and calls to the function all use the same scopes, types, and calling conventions.

可以在 c + + 代码中导致此错误,当您在类定义中包括函数原型,但故障到包括实施的函数,然后调用它。This error can be caused in C++ code when you include a function prototype in a class definition but fail to include the implementation of the function, and then call it. 若要解决此问题,请确保提供所有名为声明类的成员的定义。To fix this issue, be sure to provide a definition for all called declared members of a class.

尝试从一个抽象基类调用纯虚函数可以导致此错误。This error can be caused by an attempt to call a pure virtual function from an abstract base class. 纯虚函数具有任何基类实现。A pure virtual function has no base class implementation. 若要解决此问题,请确保所有调用虚函数实现。To fix this issue, make sure all called virtual functions are implemented.

此错误可能由尝试使用函数内声明的变量 (局部变量) 该函数的作用域之外。This error can be caused by trying to use a variable declared within a function (a local variable) outside the scope of that function. 若要解决此问题,删除对不在范围内,该变量的引用,或将变量移到更高的作用域。To fix this issue, remove the reference to the variable that is not in scope, or move the variable to a higher scope.

生成 ATL 项目的发布版本生成 CRT 启动代码是必需的消息时,会出现此错误。This error can occur when you build a Release version of an ATL project, producing a message that CRT startup code is required. 若要解决此问题,请执行下列操作之一To fix this issue, do one of the following,

  • 删除_ATL_MIN_CRT从列表中的预处理器定义允许 CRT 启动代码将包括在内。Remove _ATL_MIN_CRT from the list of preprocessor defines to allow CRT startup code to be included. 请参阅常规属性页 (项目)有关详细信息。See General Property Page (Project) for more information.

  • 如果可能,删除对需要 CRT 启动代码的 CRT 函数的调用。If possible, remove calls to CRT functions that require CRT startup code. 相反,使用它们的 Win32 等效项。Instead, use their Win32 equivalents. 例如,使用 lstrcmp 而不是 strcmpFor example, use lstrcmp instead of strcmp. 需要 CRT 启动代码的已知的功能是一些字符串和浮点函数。Known functions that require CRT startup code are some of the string and floating point functions.

当项目缺少对库的引用时,会出现此错误 (。LIB) 或对象 (。OBJ) 文件。This error can occur when the project is missing a reference to a library (.LIB) or object (.OBJ) file. 若要解决此问题,请到您的项目添加到所需的库或对象文件的引用。To fix this issue, add a reference to the required library or object file to your project. 有关详细信息,请参阅用作链接器输入的.lib 文件For more information, see .lib Files as Linker Input.

如果您使用可能发生此错误/NODEFAULTLIB/Zl选项。This error can occur if you use the /NODEFAULTLIB or /Zl options. 当指定这些选项时,包含所需的代码的库除非显式包含了它们并未链接到项目。When you specify these options, libraries that contain required code are not linked into the project unless you have explicitly included them. 若要解决此问题,请显式包括链接命令行使用的所有库。To fix this issue, explicitly include all the libraries you use on the link command line. 如果您看到许多缺少 CRT 或标准库函数名称时使用这些选项,显式包括 CRT 和标准库 Dll 或库文件的链接中。If you see many missing CRT or Standard Library function names when you use these options, explicitly include the CRT and Standard Library DLLs or library files in the link.

如果使用编译 /clr选项,可以对.cctor 缺少引用。If you compile using the /clr option, there can be a missing reference to .cctor. 若要解决此问题,请参阅混合程序集初始化有关详细信息。To fix this issue, see Initialization of Mixed Assemblies for more information.

如果时生成的应用程序的调试版本链接到发布模式库,可以发生此错误。This error can occur if you link to the release mode libraries when building a debug version of an application. 同样,如果使用选项 /MTd/MDd或定义_DEBUG,然后链接到发布库,您将会发现很多潜在无法解析的外部,在其他问题。Similarly, if you use options /MTd or /MDd or define _DEBUG and then link to the release libraries, you should expect many potential unresolved externals, among other problems. 链接发布模式生成的调试库还会导致类似问题。Linking a release mode build with the debug libraries also causes similar problems. 若要解决此问题,请确保在您的调试版本中使用调试库,并在 retail 零售库生成。To fix this issue, make sure you use the debug libraries in your debug builds, and retail libraries in your retail builds.

如果你的代码引用符号从一个版本的库,但提供给链接器库的不同版本,可以发生此错误。This error can occur if your code refers to a symbol from one version of a library, but you supply a different version of the library to the linker. 通常情况下,不能混合对象文件或为不同版本的编译器生成的库。Generally, you can't mix object files or libraries that are built for different versions of the compiler. 新版本中随附的库可能包含不能在早期版本中,以及进行相反转换中包含的库中找到的符号。The libraries that ship in a new version may contain symbols that cannot be found in the libraries included with previous versions, and vice-versa. 若要解决此问题,请将它们链接在一起之前生成的所有对象文件和库使用相同版本的编译器。To fix this issue, build all the object files and libraries with the same version of the compiler before linking them together.

  • 工具|选项|项目|VC + + 目录对话框中,在库文件的所选内容,可以更改库搜索顺序。The Tools | Options | Projects | VC++ Directories dialog, under the Library files selection, allows you to change the library search order. 在项目属性页对话框中的链接器文件夹也可能包含可能是过期的路径。The Linker folder in the project's Property Pages dialog box may also contain paths that could be out of date.

  • 新的 SDK 安装 (可能是到其他位置) 和搜索顺序不会更新以指向新位置时,可能会出现此问题。This problem may appear when a new SDK is installed (perhaps to a different location), and the search order is not updated to point to the new location. 通常情况下,应将路径放到新的 SDK include 和 lib 目录默认 Visual c + + 位置的前面。Normally, you should put the path to new SDK include and lib directories in front of the default Visual C++ location. 此外,包含嵌入的路径的项目可能仍然指向旧路径有效,但已过期的情况下安装到其他位置的新版本添加的新功能。Also, a project containing embedded paths may still point to old paths that are valid, but out of date for new functionality added by the new version that is installed to a different location.

  • 如果您在命令行生成并创建了自己的环境变量,请验证工具、 库和标头文件的路径转到一致的版本。If you build at the command line and have created your own environment variables, verify that the paths to tools, libraries, and header files go to a consistent version. 有关详细信息,请参阅为命令行生成设置路径和环境变量For more information, see Set the Path and Environment Variables for Command-Line Builds

目前没有标准c + + 命名编译器供应商之间、 甚至之间不同版本的编译器。There is currently no standard for C++ naming between compiler vendors or even between different versions of a compiler. 因此,链接用其他编译器编译对象文件可能不生成相同的命名方案,并因此导致错误 LNK2001。Therefore, linking object files compiled with other compilers may not produce the same naming scheme and thus cause error LNK2001.

混合内联和非内联编译选项上不同的模块会导致 LNK2001。Mixing inline and non-inline compile options on different modules can cause LNK2001. 如果使用函数内联开启创建 c + + 库 (/ob1/ob2) 描述函数的相应标头文件具有内联处于关闭状态,但 (没有inline关键字),此错误会发生。If a C++ library is created with function inlining turned on (/Ob1 or /Ob2) but the corresponding header file describing the functions has inlining turned off (no inline keyword), this error occurs. 若要解决此问题,定义的函数inline在其他源文件中包含的标头文件中。To fix this issue, define the functions inline in the header file you include in other source files.

如果您使用#pragma inline_depth编译器指令,请确保你已设置了 2 个或更高版本的值,并确保也使用/ob1/ob2编译器选项。If you use the #pragma inline_depth compiler directive, make sure you have a value of 2 or greater set, and make sure you also use the /Ob1 or /Ob2 compiler option.

如果省略该链接可能出现此错误选项 /NOENTRY 时创建纯资源 DLL。This error can occur if you omit the LINK option /NOENTRY when you create a resource-only DLL. 若要解决此问题,请添加到链接命令 /NOENTRY 选项。To fix this issue, add the /NOENTRY option to the link command.

如果在项目中使用不正确 /SUBSYSTEM 或 /ENTRY 设置,可以发生此错误。This error can occur if you use incorrect /SUBSYSTEM or /ENTRY settings in your project. 例如,如果你编写的控制台应用程序,并指定 /subsystem: windows,则无法解析的外部错误生成的WinMainFor example, if you write a console application and specify /SUBSYSTEM:WINDOWS, an unresolved external error is generated for WinMain. 若要解决此问题,请确保匹配到项目类型的选项。To fix this issue, make sure you match the options to the project type. 有关这些选项和入口点的详细信息,请参阅/SUBSYSTEM/ENTRY链接器选项。For more information on these options and entry points, see the /SUBSYSTEM and /ENTRY linker options.

导出的符号问题Exported symbol issues

找不到.def 文件中列出的导出时,将发生此错误。This error occurs when an export listed in a .def file is not found. 这可能是因为它不存在、 拼写错误,或使用 c + + 修饰名称。This could be because it does not exist, is spelled incorrectly, or uses C++ decorated names. .Def 文件才会修饰的名。A .def file does not take decorated names. 若要解决此问题,请删除不需要的导出,并使用extern "C"导出符号的声明。To fix this issue, remove unneeded exports, and use extern "C" declarations for exported symbols.

无法解析的外部符号是什么?What is an unresolved external symbol?

一个符号是函数或由已编译的对象文件或库在内部使用的全局变量的名称。A symbol is the name for a function or global variable used internally by a compiled object file or library. 符号是由定义对象文件中的全局变量,或对于函数,其中分配存储放置在函数体的已编译的代码的位置。A symbol is defined in the object file where storage is allocated for a global variable, or for a function, where the compiled code for the function body is placed. 的外部符号是一个符号的引用,即,使用或调用在一个对象文件中,但在不同的库或对象文件中定义。An external symbol is a symbol that's referenced, that is, used or called in one object file, but defined in a different library or object file. 导出符号是一种进行公开的对象文件或将其定义的库。An exported symbol is one that's made publicly available by the object file or library that defines it. 链接器必须解决,或找到的匹配定义,每个引用的对象文件时将其链接到应用程序或 DLL 的外部符号。The linker must resolve, or find the matching definition for, every external symbol referenced by an object file when it is linked into an application or DLL. 链接器将生成错误时它不能通过任何链接的文件中查找匹配的导出的符号解析的外部符号。The linker generates an error when it can't resolve an external symbol by finding a matching exported symbol in any of the linked files.

使用修饰的名以找出错误Use the decorated name to find the error

C + + 编译器和链接器使用名称修饰,也称为名称重整、 有关变量的类型或返回类型、 参数类型、 作用域,以及调用的额外信息进行编码中的符号名称的函数的约定。The C++ compiler and linker use Name Decoration, also known as name-mangling, to encode extra information about the type of a variable or the return type, parameter types, scope, and calling convention of a function in the symbol name. 此修饰的名是链接器搜索用于解析外部符号的符号名称。This decorated name is the symbol name the linker searches for to resolve external symbols.

由于的额外信息变得符号名称的一部分,如果函数或变量的声明不完全匹配的函数或变量的定义会导致链接错误。Because the extra information becomes part of the symbol name, a link error can result if the declaration of a function or variable does not exactly match the definition of the function or variable. 这可能是即使相同的标头文件用于调用的代码和定义代码,如果编译的源文件时使用不同的编译器标志。This can happen even if the same header file is used in both the calling code and the defining code, if different compiler flags are used when compiling the source files. 例如,如果你的代码编译为使用收到此错误__vectorcall调用约定,但您链接到要求客户端调用使用默认的库__cdecl__fastcall调用约定。For example, you can get this error if your code is compiled to use the __vectorcall calling convention, but you link to a library that expects clients to call it using the default __cdecl or __fastcall calling convention. 在这种情况下,符号不匹配,因为不同的调用约定In this case, the symbols do not match because the calling conventions are different

为了帮助你找出这种错误的原因,链接器错误消息显示这两个"友好名称,"源代码和未解析的外部符号的修饰的名称 (在括号内) 中使用的名称。To help you find the cause of this kind of error, the linker error message shows you both the "friendly name," the name used in source code, and the decorated name (in parentheses) for the unresolved external symbol. 不需要知道如何将转换为修饰的名,以便能够将其与其他修饰名称进行比较。You don't need to know how to translate the decorated name to be able to compare it with other decorated names. 可以使用命令行工具附带编译器要比较的预期的符号名称和实际的符号名称:You can use command line tools that are included with the compiler to compare the expected symbol name and the actual symbol name:

  • /Exports/ 符号选项的 DUMPBIN 命令行工具可帮助你发现.dll 和对象或库文件中定义了哪些符号。The /EXPORTS and /SYMBOLS options of the DUMPBIN command line tool can help you discover which symbols are defined in your .dll and object or library files. 可以使用此验证导出的修饰名称的修饰名称链接器搜索的匹配项。You can use this to verify that the exported decorated names match the decorated names the linker searches for.

在某些情况下,链接器仅可以报告符号的修饰的名称。In some cases, the linker can only report the decorated name for a symbol. UNDNAME 命令行工具可用于获取修饰名的未修饰的形式。You can use the UNDNAME command line tool to get the undecorated form of a decorated name.

其他资源Additional resources

LNK2001 可能的原因和解决方案的详细信息,请参阅堆栈溢出问题什么是未定义引用/未解析的外部符号错误以及如何修复此错误?For more information about possible causes and solutions for LNK2001, see the Stack Overflow question What is an undefined reference/unresolved external symbol error and how do I fix it?.