zl程序教程

您现在的位置是:首页 >  其他

当前栏目

VS报错LNK2019 无法解析的外部符号 _main,函数 “int __cdecl invoke_main(void)“ (?invoke_main@@YAHXZ) 中引用了该符号的解决方法

2023-04-18 15:44:29 时间

很多C初学者或者新人在使用VS编译器编写C代码运行时提示:严重性 代码 说明 项目 文件 行 禁止显示状态错误 LNK2019 无法解析的外部符号 _main,函数 “int __cdecl invoke_main(void)” (?invoke_main@@YAHXZ) 中引用了该符号 StudyCProject E:VisualStudioProjectsStudyCProjectStudyCProjectMSVCRTD.lib(exe_main.obj) 1

在这里插入图片描述

可能的原因

有多种方法会造成此错误。 所有这些方法都涉及引用链接器无法解析或无法查找其定义的函数或变量。 编译器可以识别未声明符号的情况,但无法判断未定义符号的情况。 这是因为定义可能位于不同的源文件或库中。 如果引用了未定义的符号,链接器会生成未解析的外部 (external) 符号错误。

以下是一些导致 LNK2019 的常见问题:

原因1:包含符号定义的源文件未编译

在 Visual Studio 中,确保将定义符号的源文件编译为项目的一部分。 检查中间生成输出目录中是否有匹配的 .obj 文件。

如果源文件未编译,请右键单击“解决方案资源管理器”中的文件,然后选择“属性”以检查文件的属性。 “配置属性”>“常规”页应显示 C/C++ 编译器的项类型。 在命令行上,确保编译了包含定义的源文件。

原因2:包含符号定义的目标文件或库未链接

在 Visual Studio 中,确保包含符号定义的对象文件或库作为项目的一部分链接。 在命令行上,确保要链接的文件列表包含对象文件或库。

原因3:符号声明与符号定义的拼写不一样

验证在声明和定义中以及在使用或调用符号的任何地方使用了正确的拼写和大写。

原因4:使用了函数,但是参数的类型或数量与函数定义不匹配

函数声明必须匹配定义。 确保函数调用与声明匹配,并且声明与定义匹配。 调用函数模板的代码还必须具有与定义相同的模板参数的匹配函数模板声明。 有关模板声明不匹配的示例,请参阅“示例”部分中的示例 LNK2019e.cpp。

原因5:声明了函数或变量,但是未对其进行定义

当头文件中存在声明但未实现匹配定义时,可能会发生 LNK2019。 对于成员函数或 static 数据成员,实现必须包括类范围选择器。 有关示例,请参见 Missing Function Body or Variable

原因6:函数声明和函数定义之间的调用约定不同

某些调用约定(__cdecl__stdcall__fastcall__vectorcall)作为修饰名称的一部分进行编码。 确保调用约定是相同的。

原因7:符号在 C 文件中定义,但未使用 extern “C” 在 C++ 文件中进行声明

编译为 C 的文件将为符号创建修饰名称,这些名称不同于在 C++ 文件中声明的相同符号的修饰名称,除非使用 extern “C” 修饰符。 确保声明与每个符号的编译链接匹配。 同样,如果在 C 程序将使用的 C++ 文件中定义符号,请在定义中使用 extern “C” 。

原因8:符号定义为 static,并随后在文件外部引用

不同于 C,在 C++ 中,全局常量 (constants) 具有 static 链接。 若要避开此限制,可以在头文件中包含 const 初始化,并在 .cpp 文件中包含该头文件,或者你可以使变量成为非 const 并使用 const 引用来进行访问。

原因9:未定义类的 static 成员

static 类成员必须具有唯一的定义,否则将违反单个定义规则。 无法以内联方式定义的 static 类成员必须通过使用其完全限定名称在一个源文件中进行定义。 如果根本没有进行定义,链接器会生成 LNK2019。

原因10:生成依赖项仅在解决方案中定义为项目依赖项

在早期版本的 Visual Studio 中,此级别的依赖已足够。 但是,从 Visual Studio 2010 开始,Visual Studio 需要项目到项目引用。 如果你的项目没有项目到项目引用,你可能收到此链接器错误。 添加项目到项目引用以修复此错误。

原因11:未定义入口点

应用程序代码必须定义适当的入口点:对于控制台应用程序,为 mainwmain,对于 Windows 应用程序,为 WinMainwWinMain。 有关详细信息,请参阅 main 函数和命令行参数WinMain 函数。 若要使用自定义入口点,请指定 /ENTRY(入口点符号)链接器选项。

原因12:通过使用 Windows 应用程序的设置生成控制台应用程序

如果错误消息类似于 function_name 函数中引用的未解析外部 (external) 符号 WinMain,请使用 /SUBSYSTEM:CONSOLE 而不是 /SUBSYSTEM:WINDOWS 进行链接。 有关此设置的详细信息以及如何在 Visual Studio 中设置此属性的说明,请参阅 /SUBSYSTEM(指定子系统)。

原因13:尝试将 64 位库链接到 32 位代码,或将 32 位库链接到 64 位代码

必须针对与你的代码相同的体系结构,编译链接到代码的库和目标文件。 确保针对与你的项目相同的体系结构编译项目引用的库。 确保 /LIBPATH/LIBPATH 或其他的库目录性属性指向为正确体系结构生成的库。

原因14:你为在不同源文件中内联的函数使用了不同的编译器选项

使用 .cpp 文件中定义的内联函数并在不同源文件中混合使用函数内联编译器可能会导致 LNK2019。 有关详细信息,请参阅 Function Inlining Problems

原因15:在自动变量范围外使用自动变量

自动(函数范围)变量仅可在该函数的范围内使用。 这些变量不可声明为 extern ,也不能在其他源文件中使用。 有关示例,请参见 Automatic (Function Scope) Variables

原因16:调用内部函数或将参数类型传递到目标体系结构不支持的内部函数

例如,如果你使用 AVX2 内部函数,但未指定 /ARCH:AVX2 编译器选项,则编译器假定该内部函数是外部 (external) 函数。 编译器不会生成内联指令,而是生成对与内部函数同名的外部 (external) 符号的调用。 当链接器尝试找到此缺失函数的定义时,它会生成 LNK2019。 确保只使用了目标体系结构支持的内部函数和类型。

原因17:你将使用和未使用本机 wchar_t 的代码混合在一起

在 Visual Studio 2005 中完成的 C++ 语言一致性工作使 wchar_t 成为默认本机类型。 如果并非所有文件都已经使用相同的 /Zc:wchar_t 设置进行编译,那么类型引用可能无法解析为兼容类型。 确保所有库中的 wchar_t 类型和对象文件都兼容。 从 wchar_t typedef 进行更新,或者在编译时使用一致的 /Zc:wchar_t 设置。

原因18:链接旧式静态 (static) 库时收到关于 printfscanf 函数的错误

使用 Visual Studio 2015 之前的 Visual Studio 版本生成的静态 (static) 库在与 UCRT 链接时可能出现 LNK2019 错误。 UCRT 头文件 <stdio.h><conio.h><wchar.h> 现在将许多 printfscanf 变体定义为 inline 函数。 内联函数通过一小部分通用函数实现。 标准 UCRT 库中不支持单独导出内联函数,这些库仅导出通用函数。 可通过多种方法来解决此问题。 建议使用当前版本的 Visual Studio 重新生成旧版库。 请确保库代码将标准标头用于导致错误的 printfscanf 函数的定义。 如果无法重新生成旧版库,另一个选项是将 legacy_stdio_definitions.lib 添加到所链接的库的列表。 此库文件为 UCRT 标头中的内联函数 printfscanf 提供符号。 有关详细信息,请参阅潜在的升级问题概述中的“库”部分。

原因19:第三方库问题和 vcpkg

如果在尝试将第三方库配置为生成的一部分时看到此错误,请考虑使用 vcpkg。 vcpkg 是一个 C++ 包管理器,它使用现有的 Visual Studio 工具来安装和生成库。 vcpkg 支持一个庞大且不断增长的第三方库列表。 它将成功生成所需的所有配置属性和依赖项设置为项目的一部分。

示例

以下是一些导致 LNK2019 错误的代码示例,以及关于如何修复错误的信息。

示例1:声明了符号,但是未对其进行定义

在此示例中,声明了外部 (external) 变量,但未对其进行定义:

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

以下是另一个示例,其中变量和函数被声明为 extern 但未提供定义:

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

除非在生成所含的一个文件中定义了 ig,否则链接器会生成 LNK2019。 你可以通过将包含定义的源代码文件作为编译的一部分包括在其中来修复错误。 或者,你可以将包含定义的 .obj 文件或 .lib 文件传递给链接器。

示例2:声明了 static 数据成员,但是未对其进行定义

声明了 static 数据成员,但未对其进行定义时也可能发生 LNK2019。 以下示例生成 LNK2019,并演示如何修复此错误。

// 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;
}

示例3:声明参数与定义不匹配

调用函数模板的代码必须具有匹配的函数模板声明。 声明必须包括与定义相同的模板参数。 以下示例在用户定义的运算符上生成 LNK2019,并演示如何修复此错误。

// LNK2019e.cpp
// compile by using: cl /EHsc LNK2019e.cpp
// LNK2019 expected
#include <iostream>
using namespace std;

template<class T> class
Test {
   // The operator<< declaration doesn't 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
}

示例4:wchar_t 类型定义不一致

此示例创建具有使用 WCHAR 的导出的 DLL,其解析为 wchar_t/code>。

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

下一示例使用上一示例中的 DLL,并生成 LNK2019,因为 unsigned short*WCHAR* 的类型不同。

// LNK2019h.cpp
// compile by using: cl /EHsc LNK2019h LNK2019g.lib
// LNK2019 expected
__declspec(dllimport) void func(unsigned short*);

int main() {
   func(0);
}

若要解决此错误,请将 unsigned short 更改为 wchar_tWCHAR,或使用 /Zc:wchar_t- 编译 LNK2019g.cpp。

另请参阅

有关 LNK2019、LNK2001 和 LNK1120 错误的可能原因和解决方案的详细信息,请参阅 Stack Overflow 问题:What is an undefined reference/unresolved external symbol error and how do I fix it?

解决

博主VS报错LNK2019的实际原因是 原因11:未定义入口点,就是 main 方法名写错成了 mian 方法名导致的.
在这里插入图片描述

修改成正确的main方法名问题解决

在这里插入图片描述

参考文献

链接器工具错误 LNK2019