在同一编译器 (vc12) 上编译时,是什么导致了名称的差异?

What causes difference in mangled names when compiling on the same compiler (vc12)?

我目前正在尝试用我的项目编译和 link CppUTest 库。我使用 CMake 为 CppUTest 库创建了一个 Visual Studio 2013 解决方案并构建了它。

但是,当我 link 为我的应用程序创建 CppUTest.lib 时,我收到一个 linker 错误,告诉我它找不到像

这样的多个符号

??0Utest@@QAE@XZ)

?RunAllTests@CommandLineTestRunner@@SAHHPAPAD@Z

现在,当我在 lib 上使用 dumpbin.exe 和选项 /LINKERMEMBER 时,我在库中得到了一个包含名称的符号列表

??0Utest@@QEAA@XZ

?RunAllTests@CommandLineTestRunner@@SAHHPEAPEAD@Z

所以实际存在的名称与我的项目期望的名称略有不同,我不知道是什么导致了这个问题。是否有任何编译选项导致这些更改,或者我是否使用了不同的编译器,尽管我认为它是相同的?

运行 来自 Visual Studio 命令提示符的 undname.exe utility。你得到:

Undecoration of :- "??0Utest@@QAE@XZ"
is :- "public: __thiscall Utest::Utest(void)"

Undecoration of :- "??0Utest@@QEAA@XZ"
is :- "public: __cdecl Utest::Utest(void) __ptr64"

很明显,这是 Utest 的默认构造函数 class。请注意调用约定有何不同,__thiscall 与 __cdecl。以及库版本如何具有 __ptr64 属性。

您看到该属性出现在 64 位函数上。 x64只有一种调用约定,不区分__cdecl和__thiscall.

所以它应该开始变得明显,链接器需要第一个,构造函数的 32 位版本。您提供的 64 位版本永远无法工作,因为您不能混合使用 32 位和 64 位代码。对此也应该有一个响亮的警告,不要忽视这样的警告。

Link 到这个库的 32 位版本来解决你的问题。或者构建程序的 x64 版本。