链接问题(VC6)

时间:2008-08-08 13:13:09

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

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

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

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

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

错误(GetMessage)中提到的函数已实现,但它是一个虚函数,因此其他类可以在需要时覆盖它。但是看起来编译器已经把它变成了Ansi版本,但我找不到控制它的设置中的任何选项。我怀疑这可能是问题,但由于库的选项方式很少,我无法确切知道。但是两个项目都在编译器选项中指定_MBCS。

  

--------------------配置:TestComms - Win32 Debug --------------------链接... Comms.lib(IOCompletionPort.obj)   :错误LNK2001:未解析的外部符号“public:virtual class   的std :: basic_string的,类   std :: allocator> __thiscall   Comms :: Exception :: GetMessageA(void)const“(?GetMessageA @   例外@ @@通讯科UBE?AV?$ basic_string的@ DU?$ char_traits @ d @ @@ STD V'$分配器@ d @ @@ 2 STD @@ XZ)   Debug / TestComms.exe:致命错误LNK1120:1个未解析的外部   执行link.exe时出错。

     

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

有什么建议吗?我早上大部分时间都已经失去了这个,也不想在下午的大部分时间里失去。

5 个答案:

答案 0 :(得分:4)

一种可能性在于Win32 ANSI / Unicode“name-mangling”,它将符号GetMessage转换为GetMessageAGetMessageW。有三种可能性:

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

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

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

  4. 如果您以触发两种不同方案的方式编译了两个不同的文件,则会出现链接器错误。错误消息表明Comms::Exception类是上面的#2的实例 - 也许是在某些地方没有加载过windows.h?

    我在你的位置做的其他事情,就像例行公事一样:

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

    2)执行“build clean”然后手动验证,必要时删除任何额外的目标文件。

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

    编辑:与格式战斗:(

答案 1 :(得分:1)

@Curt:我觉得你来的最近了。我没有对此进行测试,但我认为我在原始问题中给出了答案。

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

答案 2 :(得分:0)

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

  1. 证实了这一点。没有什么不合适的。
  2. 我已经完成了 - 删除了构建目录
  3. 我从不使用硬编码路径。

答案 3 :(得分:0)

假设您没有使用项目设置来删除您不应该拥有的内容(这是我希望User32.lib之类的外部依赖项):

检查工具|选项|目录|图书馆(从内存开始)并确保你不会错过普通全园的各种lib目录(再次,在我面前没有VC6,我不能告诉你它们是什么)

答案 4 :(得分:0)

这是Microsoft处理ANSI与Uni​​code API的方式的一般问题。由于它们全部(或几乎全部)通过为函数名定义宏来解析函数名的'A'或'W'版本,因此您无法在命名空间/ class / struct / enum /中安全地拥有标识符。与Windows API名称匹配的函数。

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