我打开了一个旧工作区,它是一个libray及其测试工具。它曾经工作正常,但现在没有,旧版本的代码不能使用相同的错误。我试过重新创建项目,也导致了同样的错误。项目设置中似乎没有任何错误,生成的代码在主应用程序中有效。
我已经删除了大部分文件并将其降至最低限度以生成错误。不幸的是,我无法发布项目,因为它在生产代码中使用。
我得到的LNK2001链接器错误通常意味着我已离开库或忘记实现虚函数。然而,这是标准模板库的一部分 - 并且是那个标题。
在IOCompletionPort.obj中列出的问题代码实际上并没有直接使用std::string
,而是调用了一个类:Comms::Exception
接受std::string
和价值GetLastError
或WSAGetLastError
。
错误(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个警告
有什么建议吗?我早上大部分时间都已经失去了这个,也不想在下午的大部分时间里失去。
答案 0 :(得分:4)
一种可能性在于Win32 ANSI / Unicode“name-mangling”,它将符号GetMessage
转换为GetMessageA
或GetMessageW
。有三种可能性:
尚未加载Windows.h,因此GetMessage
保持GetMessage
Windows.h加载了符号设置为ANSI,因此GetMessage
变为GetMessageA
Windows.h加载了为Unicode设置的符号,因此GetMessage
变为GetMessageW
如果您以触发两种不同方案的方式编译了两个不同的文件,则会出现链接器错误。错误消息表明Comms::Exception
类是上面的#2的实例 - 也许是在某些地方没有加载过windows.h?
我在你的位置做的其他事情,就像例行公事一样:
1)确保我的包含和库路径不包含任何我不期望的内容。
2)执行“build clean”然后手动验证,必要时删除任何额外的目标文件。
3)确保include语句中没有任何硬编码路径,这并不代表最初重建项目时的含义。
编辑:与格式战斗:(
答案 1 :(得分:1)
GetMessage是Windows.h中的一个定义,包含在ifndef块中,用于在Ansi(GetMessageA)和Unicode(GetMessageW)之间切换。
答案 2 :(得分:0)
windows.h在IOCompletionPort.h的顶部被声明为一个包含 - 我厌倦了看到7行只包含1个文件所以我把它包装成自己的文件并包含它本身。这还包含一些额外的#defines(即ULONG_PTR),因为我们的主应用程序无法使用安装的Platform SDK进行编译: - (
答案 3 :(得分:0)
假设您没有使用项目设置来删除您不应该拥有的内容(这是我希望User32.lib之类的外部依赖项):
检查工具|选项|目录|图书馆(从内存开始)并确保你不会错过普通全园的各种lib目录(再次,在我面前没有VC6,我不能告诉你它们是什么)
答案 4 :(得分:0)
这是Microsoft处理ANSI与Unicode API的方式的一般问题。由于它们全部(或几乎全部)通过为函数名定义宏来解析函数名的'A'或'W'版本,因此您无法在命名空间/ class / struct / enum /中安全地拥有标识符。与Windows API名称匹配的函数。
windows.h宏在所有其他名称空间上运行粗略。