链接问题(VC6)

时间:2020-03-05 18:38:36  来源:igfitidea点击:

我打开了一个旧的工作空间,它是一个libray及其测试工具。它曾经可以正常工作,但现在不行,并且旧版本的代码也不会因相同的错误而工作。我尝试重新创建项目,这也会导致相同的错误。在项目设置中似乎没有任何异常,并且生成的代码在主应用程序中有效。

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

我收到的LNK2001链接器错误通常表示我放弃了一个库或者忘记了实现虚函数。但是,这是标准模板库的一部分,并且是该模板的标头。

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

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

--------------------Configuration: TestComms - Win32 Debug-------------------- Linking...  Comms.lib(IOCompletionPort.obj)
  : error LNK2001: unresolved external symbol "public: virtual class
  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 : fatal error LNK1120: 1 unresolved externals 
  Error executing link.exe.
  
  TestComms.exe - 2 error(s), 0 warning(s)

有什么建议?我已经失去了大部分时间,也不想失去大部分时间。

解决方案

回答

一种可能是Win32 ANSI / Unicode"名称修改",它将符号" GetMessage"转换为" GetMessageA"或者" GetMessageW"。有三种可能性:

  • Windows.h尚未加载,因此GetMessage保持为GetMessage。
  • Windows.h加载了为ANSI设置的符号,因此GetMessage变为GetMessageA
  • Windows.h加载了为Unicode设置的符号,因此GetMessage变为GetMessageW

如果我们以触发两种不同情况的方式编译了两种不同的文件,则会出现链接器错误。错误消息表明Comms :: Exception类是上面#2的实例-也许是在未加载windows.h的地方使用的?

作为例行事务,我会代替我们执行其他操作:

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

2)执行"内部清理",然后手动进行验证,并在必要时删除所有多余的目标文件。

3)确保include语句中没有任何硬编码的路径,这些路径并不意味着它们在最初重建项目时的含义。

编辑:与格式战斗:(

回答

在IOCompletionPort.h的顶部将windows.h声明为包含,我讨厌看到7行仅包含1个文件,因此我将其包装成自己的文件并包含该文件。这还包含一些添加的#define(即ULONG_PTR),因为我们的主应用程序无法与已安装的Platform SDK一起编译:-(

  • 可以确认了。没有什么不妥当的。
  • 我已经完成了-删除了构建目录
  • 我从不使用硬编码的路径。

回答

假设我们没有对Project设置感到困惑,删除了我们不应该拥有的东西(这是我希望像User32.lib这样的外部依赖项所在的位置)的方法:

检查工具|选项|目录|库(从内存中移出),并确保我们没有丢失通用花园的各种lib目录(同样,在我面前没有VC6的情况下,我无法告诉我们它们是什么)

回答

@Curt:我想你来得最近。我还没有测试过,但是我想我在最初的问题中给出了答案。

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

回答

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

Windows.h宏在所有其他命名空间上运行不便。