11

我打开了一个旧工作区,它是一个库及其测试工具。它过去可以正常工作,但现在不能,旧版本的代码也不能正常工作,出现相同的错误。我试过重新创建项目,这也会导致同样的错误。项目设置中似乎没有任何问题,并且生成的代码在主应用程序中有效。

我已经删除了大部分文件并将其降至最低限度以生成错误。不幸的是,我无法发布该项目,因为它用于生产代码。

我得到的 LNK2001 链接器错误通常意味着我已经离开了一个库或忘记实现一个虚函数。然而,这是标准模板库的一部分 - 并且是一个标题。

在 IOCompletionPort.obj 中列为有问题的代码实际上并没有std::string直接使用,而是调用了一个类:Comms::Exception接受 astd::stringGetLastErroror的值WSAGetLastError

错误()中提到的函数GetMessage已实现,但它是一个虚函数,因此其他类可以在需要时覆盖它。但是,编译器似乎已将其作为 Ansi 版本,但我在设置中找不到任何可以控制它的选项。我怀疑这可能是问题所在,但由于图书馆的选择方式很少,我无法确定。但是,这两个项目都在编译器选项中指定 _MBCS。

--------------------配置:TestComms - Win32 调试--------------------链接... Comms.lib(IOCompletionPort.obj):错误 LNK2001:无法解析的外部符号“公共:虚拟类 std::basic_string,class std::allocator > __thiscall Comms::Exception::GetMessageA(void)const”(?GetMessageA@ Exception@ Comms@@UBE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) Debug/TestComms.exe : 致命错误 LNK1120: 1 unresolved externals 执行错误链接.exe。

TestComms.exe - 2 个错误,0 个警告

有什么建议么?我早上的大部分时间都为此而迷失,也不想下午的大部分时间都迷失。

4

5 回答 5

6

一种可能性在于 Win32 ANSI/Unicode “名称修改”,它将符号GetMessage转换为GetMessageAGetMessageW。有三种可能:

  1. Windows.h 尚未加载,因此GetMessage保留GetMessage

  2. Windows.h 加载了为 ANSI 设置的符号,因此GetMessage变为GetMessageA

  3. Windows.h 加载了为 Unicode 设置的符号,因此GetMessage变为GetMessageW

如果您以触发两种不同场景的方式编译了两个不同的文件,您将收到链接器错误。错误消息表明Comms::Exception该类是上面 #2 的实例——也许它在 windows.h 尚未加载的地方使用?

我会代替你做的其他事情,就像例行公事一样:

1) 确保我的包含和库路径不包含我不期望的任何内容。

2) 执行“构建清理”,然后手动验证它,如有必要,删除任何额外的目标文件。

3) 确保 include 语句中没有任何硬编码路径与最初重建项目时的含义不同。

编辑:与格式作斗争:(

于 2008-08-08T13:30:03.507 回答
1

@Curt:我认为你是最接近的。我没有对此进行测试,但我想我在最初的问题中给出了答案。

GetMessage是 Windows.h 中的一个定义,包装在 ifndef 块中,用于在 Ansi (GetMessageA) 和 Unicode (GetMessageW) 之间切换。

于 2008-08-09T10:50:00.880 回答
0

windows.h 在 IOCompletionPort.h 的顶部被声明为包含 - 我厌倦了看到 7 行只是为了包含 1 个文件,所以我将它包装成自己的文件并包含它自己。这还包含一些额外的#defines(即 ULONG_PTR),因为我们的主应用程序不会在安装了 Platform SDK 的情况下编译:-(

  1. 这得到了证实。没有什么是不合适的。
  2. 我已经做到了 - 删除了构建目录
  3. 我从不使用硬编码路径。
于 2008-08-08T13:52:29.013 回答
0

假设您没有在项目设置中删除您不应该拥有的东西(这是我期望像 User32.lib 这样的外部依赖项):

检查工具 | 选项 | 目录 | 图书馆(从这里记忆中)并确保您不会错过通用的所有花园品种 lib 目录(再次,在我面前没有 VC6,我无法告诉您它们是什么)

于 2008-08-08T13:54:35.763 回答
0

这是 Microsoft 处理 ANSI 与 Unicode API 的方式的普遍问题。由于它们都是(或几乎全部)通过为解析为函数名称的“A”或“W”版本的函数名称定义宏来完成的,因此您不能安全地在命名空间/类/结构/枚举/中拥有标识符与 Windows API 名称匹配的函数。

windows.h 宏在所有其他命名空间上运行粗暴。

于 2008-09-16T18:52:32.827 回答