名称修饰

名称修饰通常是指 C++ 命名约定,但也可应用于多个 C 情形。 默认情况下,C++ 使用函数名、参数和返回类型来为该函数创建链接器名称。 请考虑以下函数声明:

void CALLTYPE test(void);

下表显示了各种调用约定的链接器名称。

调用约定 extern "C".c 文件 .cpp.cxx/TP
C 命名约定 (__cdecl) _test ?test@@ZAXXZ
Fastcall 命名约定 (__fastcall) @test@0 ?test@@YIXXZ
标准调用命名约定 (__stdcall) _test@0 ?test@@YGXXZ
Vectorcall 命名约定 (__vectorcall) test@@0 ?test@@YQXXZ

使用 extern "C" 从 C++ 调用 C 函数。 extern "C" 强制对非类 C++ 函数使用 C 命名约定。 请注意编译器开关 /Tc/Tp,它们通知编译器忽略文件扩展名并分别将文件编译为 C 或 C++。 这些选项可能会导致不需要的链接器名称。

具有不匹配的参数的函数原型也会导致此错误。 名称修饰将函数的参数合并到最终修饰的函数名中。 使用与函数声明的参数类型不匹配的参数类型调用函数可能会导致 LNK2001。

目前,在编译器供应商之间,甚至在同一编译器的不同版本之间尚不存在 C++ 命名标准。 链接用其他编译器编译的对象文件可能不会产生相同的命名方案,从而导致无法解析的外部对象。

另请参阅

链接器工具错误 LNK2001