Linker Tools Error LNK2019官方错误原因和个人碰到的一些问题

Linker Tools Error LNK2019

Visual Studio 2015
 

For the latest documentation on Visual Studio 2017, see Visual Studio 2017 Documentation.

unresolved external symbol 'symbol' referenced in function 'function'

The linker could not find a definition for external symbol "symbol" used in function "function".

There are many issues that can cause this error. This topic will help you identify the cause and find a solution.

symbol is the name the compiler uses for a function or global variable. An external symbol is the name used to refer to a symbol that is defined in a different source or object file. The linker must resolve, or find the definition for, the external symbol for every function or global variable used by each compiled file when it is linked into an application or DLL. If the linker can't find a matching definition for an external symbol in any of the linked files, it generates LNK2019.

This error can occur if the object or library file that has the definition of a symbol is not included in the build. It can also occur if the symbol name the linker searches for does not match the name of the symbol in the library or object file that defines it. This can happen if the name in the calling code is misspelled, uses different capitalization, uses a different calling convention, or specifies different parameters.

Code that uses C++ linkage uses Name Decoration, also known as name-mangling, to encode extra information about a variable or function's type and calling convention in the symbol name. The decorated name is the name the linker searches for to resolve external symbols. Because the type information becomes part of the symbol's decorated name, LNK2019 can result if the declaration of the external symbol where it is used does not match the declaration of the symbol where it is defined. To help you find the cause of the error, the 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.

Common issues

Here are some common problems that cause LNK2019:

  • The object file or library that contains the definition of the symbol is not linked. In Visual Studio, verify that the source file that contains the definition is built and linked as part of your project. On the command line, verify that the source file that contains the definition is compiled, and that the resulting object file is included in the list of files to link.

  • The declaration of the symbol is not spelled the same as the definition of the symbol. Verify the correct spelling and capitalization is used in both the declaration and the definition, and wherever the symbol is used or called.

  • A function is used but the type or number of the parameters do not match the function definition. The function declaration must match the definition. Verify that the function call matches the declaration, and that the declaration matches the definition. Code that invokes template functions must also have matching template function declarations that include the same template parameters as the definition. For an example of a template declaration mismatch, see sample LNK2019e.cpp in the Examples section.

  • A function or variable is declared but not defined. This usually means a declaration exists in a header file, but no matching definition is implemented. For member functions or static data members, the implementation must include the class scope selector. For an example, seeMissing Function Body or Variable.

  • The calling convention is different between the function declaration and the function definition. Calling conventions (__cdecl__stdcall,__fastcall, or __vectorcall) are encoded as part of the decorated name. Verify that the calling convention is the same.

  • A symbol is defined in a C file, but declared without using extern "C" in a C++ file. Symbols defined in a file that is compiled as C have different decorated names than symbols declared in a C++ file unless you use an extern "C" modifier. Verify that the declaration matches the compilation linkage for each symbol.

    Similarly, if you define a symbol in a C++ file that will be used by a C program, use extern "C" in the definition.

  • A symbol is defined as static and then later referenced outside the file. In C++, unlike C, global constants have static linkage. To get around this limitation, you can include the const initializations in a header file and include that header in your .cpp files, or you can make the variable non-constant and use a constant reference to access it.

  • A static member of a class is not defined. A static class member must have a unique definition, or it will violate the one-definition rule. A static class member that cannot be defined inline must be defined in one source file by using its fully-qualified name. If it is not defined at all, the linker generates LNK2019.

  • A build dependency is only defined as a project dependency in the solution. In earlier versions of Visual Studio, this level of dependency was sufficient. However, starting with Visual Studio 2010, Visual Studio requires a project-to-project reference. If your project does not have a project-to-project reference, you may receive this linker error. Add a project-to-project reference to fix it.

  • You build a console application by using settings for a Windows application. If the error message is similar to unresolved external symbol WinMain referenced in functionfunction_name, link by using /SUBSYSTEM:CONSOLE instead of /SUBSYSTEM:WINDOWS. For more information about this setting, and for instructions on how to set this property in Visual Studio, see /SUBSYSTEM (Specify Subsystem).

  • You use different compiler options for function inlining in different source files. Using inlined functions defined in .cpp files and mixing function inlining compiler options in different source files can cause LNK2019. For more information, see Function Inlining Problems.

  • You use automatic variables outside their scope. Automatic (function scope) variables can only be used in the scope of that function. These variables can't be declared extern and used in other source files. For an example, see Automatic (Function Scope) Variables.

  • You call instrinsic functions or pass argument types to intrinsic functions that are not supported on your target architecture. For example, if you use an AVX2 intrinsic, but do not specify the /ARCH:AVX2 compiler option, the compiler assumes that the intrinsic is an external function. Instead of generating an inline instruction, the compiler generates a call to an external symbol with the same name as the intrinsic. When the linker tries to find the definition of this missing function, it generates LNK2019. Verify that you only use intrinsics and types supported by your target architecture.

  • You mix code that uses native wchar_t with code that doesn't. C++ language conformance work that was done in Visual C++ 2005 madewchar_t a native type by default. You must use the /Zc:wchar_t- compiler option to generate code compatible with library and object files compiled by using earlier versions of Visual C++. If not all files have been compiled by using the same /Zc:wchar_t settings, type references may not resolve to compatible types. Verify that wchar_t types in all library and object files are compatible, either by updating the types that are used, or by using consistent /Zc:wchar_t settings when you compile.

  • 个人碰到的问题:由于某些原因使用了定义了宏 _VARIADIC_MAX=10 之后,会导致不能链接超过这个参数的函数,这时候也会报LINK2019的错误,本人查找了好久,最后无意识的修改正确这个问题。希望大家能够有收获。

For more information about possible causes and solutions for LNK2019, see the Stack Overflow question What is an undefined reference/unresolved external symbol error and how do I fix it?.

Diagnosis tools

It can be difficult to tell why the linker can't find a particular symbol definition. Often the problem is that you have not included the code in your build, or build options have created different decorated names for external symbols. There are several tools and options that can help you diagnose a LNK2019 error.

  • The /VERBOSE linker option can help you determine which files the linker references. This can help you verify whether the file that contains the definition of the symbol is included in your build.

  • The /EXPORTS and /SYMBOLS options of the DUMPBIN utility can help you discover which symbols are defined in your .dll and object or library files. Verify that the exported decorated names match the decorated names the linker searches for.

  • The UNDNAME utility can show you the equivalent undecorated external symbol for a decorated name.

Examples

Here are several examples of code that causes a LNK2019 error, together with information about how to fix the error.

A symbol is declared but not defined

The following sample generates LNK2019 because an external symbol is declared but not defined:

C++
// LNK2019.cpp  
// Compile by using: cl /EHsc LNK2019.cpp  
// LNK2019 expected  
extern char B[100];   // B is not available to the linker  
int main() {  
   B[0] = ' ';   // LNK2019  
}  

Here is another example:

C++
// LNK2019c.cpp  
// Compile by using: cl /EHsc LNK2019c.cpp  
// LNK2019 expected  
extern int i;  
extern void g();  
void f() {  
   i++;  
   g();  
}  
int main() {}  

If i and g are not defined in one of the files in the build, the linker generates LNK2019. You can fix the errors by including the source code file that contains the definitions as part of the compilation. Alternatively, you can pass to the linker .obj files or .lib files that contain the definitions.

A static data member is declared but not defined

LNK2019 can also occur when a static data member is declared but not defined. The following sample generates LNK2019, and shows how to fix it.

C++
// LNK2019b.cpp  
// Compile by using: cl /EHsc LNK2019b.cpp  
// LNK2019 expected  
struct C {  
   static int s;  
};  
  
// Uncomment the following line to fix the error.  
// int C::s;  
  
int main() {  
   C c;  
   C::s = 1;  
}  

Declaration parameters do not match definition

Code that invokes template functions must have matching template function declarations. Declarations must include the same template parameters as the definition. The following sample generates LNK2019 on a user-defined operator, and shows how to fix it.

C++
// LNK2019e.cpp  
// compile by using: cl /EHsc LNK2019e.cpp  
// LNK2019 expected  
#include <iostream>  
using namespace std;  
  
template<class T> class   
Test {  
   // The operator<< declaration does not match the definition below:  
   friend ostream& operator<<(ostream&, Test&);  
   // To fix, replace the line above with the following:  
   // template<typename T> friend ostream& operator<<(ostream&, Test<T>&);  
};  
  
template<typename T>  
ostream& operator<<(ostream& os, Test<T>& tt) {  
   return os;  
}  
  
int main() {  
   Test<int> t;  
   cout << "Test: " << t << endl;   // LNK2019 unresolved external  
}  

Inconsistent wchar_t type definitions

The following sample creates a DLL that has an export that uses WCHAR, which resolves to wchar_t.

C++
// LNK2019g.cpp  
// compile with: cl /EHsc /LD LNK2019g.cpp  
#include "windows.h"  
// WCHAR resolves to wchar_t  
__declspec(dllexport) void func(WCHAR*) {}  

The following sample uses the DLL in the previous sample, and generates LNK2019 because the types unsigned short* and WCHAR* are not the same.

C++
// LNK2019h.cpp  
// compile by using: cl /EHsc LNK2019h LNK2019g.lib  
// LNK2019 expected  
__declspec(dllimport) void func(unsigned short*);  
  
int main() {  
   func(0);  
}  

To resolve this error, change unsigned short to wchar_t or WCHAR, or compile LNK2019g.cpp by using /Zc:wchar_t-.

Visual Studio中修复LNK2019错误通常涉及以下几个步骤: 1. **检查main函数**: 确保您的主入口点(main函数)已经被正确地定义和声明。如果你是新手,main函数应该像下面这样简单: ```cpp int main() { // 应该有实际的代码逻辑 return 0; } ``` 2. **查看项目设置**: 检查项目属性(Project Properties),在"Configuration Properties" -> "Linker" -> "Input" -> "Additional Dependencies"项,确保已经包含了必要的库,例如对于C++项目,可能需要`mfc.lib`, `user32.lib`, 或者`mingw32.lib`等。 3. **添加main函数到源文件**: 如果你在自定义的库或者其他模块里找到了`invoke_main`,确保在适当的位置包含了main函数的实现,并且正确引用它。如果`invoke_main`不是标准库的一部分,可能需要将它的实现复制回项目的源文件中。 4. **更新库依赖**: 确认你的工程是否正确链接到了包含main函数实现的库。如果是在第三方库中,确保正确配置了库的导入和链接过程。 5. **清理并重建项目**: 清理项目(Build > Clean Solution)然后重新构建(Build > Build Solution)看看问题是否解决了。 6. **错误排查**: 如果以上都没问题,可能需要检查是否有其他代码修改导致main函数不再可见,比如引入了新的命名空间或模块,导致原本隐式可见的main函数现在被遮蔽了。 记住,每种情况都可能有所不同,因此按照上述步骤逐一检查有助于定位和解决问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值