链接问题(VC6)

发布于 2024-07-04 02:53:13 字数 1226 浏览 5 评论 0原文

我打开了一个旧的工作区,它是一个库及其测试工具。 它曾经工作得很好,但现在不行了,旧版本的代码也无法工作,并出现相同的错误。 我尝试重新创建该项目,这也会导致相同的错误。 项目设置中似乎没有任何问题,并且生成的代码可以在主应用程序中运行。

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

我收到的 LNK2001 链接器错误通常意味着我放弃了库或忘记实现虚拟函数。 然而,这是标准模板库的一部分 - 并且是其中的标头。

IOCompletionPort.obj 中列出的存在问题的代码实际上并不直接使用 std::string,而是调用了一个执行以下操作的类:Comms::Exception接受 std::stringGetLastErrorWSAGetLastError 的值。

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

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

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

有什么建议吗? 我已经为此浪费了上午的大部分时间,并且不想也浪费下午的大部分时间。

I've opened an old workspace that is a library and its test harness. It used to work fine but now doesn't and older versions of the code don't work either with the same errors. I've tried recreating the project and that causes the same errors too. Nothing seems out of order in project settings and the code generated works in the main app.

I've stripped out most of the files and got it down to the bare minimum to generate the error. Unfortunately, I can't post the project as this is used in production code.

The LNK2001 linker error I get usually means I've left off a library or forgot to implement a virtual function. However, this is part of the standard template library - and is a header at that.

The code that is listed as having the problem in IOCompletionPort.obj doesn't actually use std::string directly, but does call a class that does: Comms::Exception accepts a std::string and the value of GetLastError or WSAGetLastError.

The function mentioned in the error (GetMessage) is implemented but is a virtual function so other classes can override it if need be. However it appears that the compiler has made it as an ANSI version, but I can't find any options in the settings that would control that. I suspect that might be the problem but since there's very little in the way of options for the library I have no way of knowing for sure. However, both projects specify _MBCS in the compiler options.

--------------------Configuration: TestComms - Win32 Debug-------------------- Linking... Comms.lib(IOCompletionPort.obj)
: error LNK2001: unresolved external symbol "public: virtual class
std::basic_string<char,struct std::char_traits,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)

Any suggestions? I've lost most of the morning to this and don't want to lose most of the afternoon too.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

情释 2024-07-11 02:53:13

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

编辑:与格式作斗争:(

One possibility lies with Win32 ANSI/Unicode "name-mangling", which turns the symbol GetMessage into either GetMessageA or GetMessageW. There are three possibilities:

  1. Windows.h hasn't been loaded, so GetMessage stays GetMessage

  2. Windows.h was loaded with symbols set for ANSI, so GetMessage becomes GetMessageA

  3. Windows.h was loaded with symbols set for Unicode, so GetMessage becomes GetMessageW

If you've compiled two different files in ways that trigger two different scenarios, you'll get a linker error. The error message indicates that the Comms::Exception class was an instance of #2, above -- perhaps it's used somewhere that windows.h hasn't been loaded?

Other things I'd do in your place, just as a matter of routine:

1) Ensure that my include and library paths don't contain anything that I'm not expecting.

2) Do a "build clean" and then manually verify it, deleting any extra object files if necessary.

3) Make sure there aren't any hardcoded paths in include statements that don't mean what they meant when the project was originally rebuilt.

EDIT: Fighting with the formatting :(

堇色安年 2024-07-11 02:53:13

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

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

@Curt: I think you came the closest. I haven't tested this but I think I sort of gave the answer in my original question.

GetMessage is a define in Windows.h wrapped in a ifndef block to switch between Ansi (GetMessageA) and Unicode (GetMessageW).

时光无声 2024-07-11 02:53:13

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

windows.h 宏对所有其他命名空间都粗暴地运行。

This is a general problem with the way Microsoft handled the ANSI vs. Unicode APIs. Since they are all (or pretty much all) done by defining macros for the function names that resolve to the 'A' or 'W' versions of the function names you cannot safely have an identifier in your namespace/class/struct/enum/function that matches a Windows API name.

The windows.h macros run roughshod over all other namespaces.

沉默的熊 2024-07-11 02:53:13

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

检查工具| 选项| 目录 | 库(这里凭记忆)并确保您没有错过 common-all-garden 品种 lib 目录(同样,如果我面前没有 VC6,我无法告诉您它们是什么)

Presuming you haven't futzed around with the Project settings deleting something you ought not have (which is where I'd expect external dependencies like User32.lib to be):

Check Tools | Options | Directories | Libraries (going from memory here) and ensure that you're not missing the common-all-garden variety lib directories (again, without VC6 in front of me, I can't tell you what they are)

终陌 2024-07-11 02:53:13

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

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

windows.h is declared at the top of IOCompletionPort.h as an include - I was sick of seeing 7 lines just to include 1 file so I have wrapped it its own file and includes that itself. This also contains some additional #defines (i.e. ULONG_PTR) as our main app won't compile with the Platform SDK installed:-(

  1. That is confirmed. Nothing is out of place.
  2. I've done that - deleted the build directories
  3. I never use hard-coded paths.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文