【问题标题】:Link issues (VC6)链接问题 (VC6)
【发布时间】:2010-09-05 13:47:37
【问题描述】:

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

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

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

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

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

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

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

有什么建议吗?我早上的大部分时间都在这件事上迷失了,我也不想下午的大部分时间都迷失了。

【问题讨论】:

    标签: c++ visual-c++ linker visual-c++-6


    【解决方案1】:

    一种可能性在于 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) 确保包含语句中没有任何硬编码路径与最初重建项目时的含义不同。

    编辑:与格式作斗争:(

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            【解决方案5】:

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

            1. 已确认。没有什么不合适的。
            2. 我已经这样做了 - 删除了构建目录
            3. 我从不使用硬编码路径。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2010-11-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-04-24
              • 2010-12-20
              • 2011-01-23
              相关资源
              最近更新 更多