【问题标题】:C++ windows code links in 64bit but not in 32bitC++ windows 代码链接 64 位但不是 32 位
【发布时间】:2017-03-13 15:40:59
【问题描述】:

我有在 Windows 上用 C++ 编写的代码。 当我将其编译为 x64 时,我的代码会编译并链接,但当我将构建配置更改为 x86 时不会。

失败是链接错误。

我正在使用来自 ntdll 的函数 RtlIsNameInExpression。

当我在 32 位模式下编译它时,我得到一个未解决的外部链接错误 (LNK2019)。

任何想法为什么会发生这种情况?

10 倍

【问题讨论】:

  • 你能发布编译器生成的完整错误吗?另外,我看到这个函数没有在任何头文件中声明。问题可能是您错误地声明了它。请同时发布声明。
  • 您应该使用LoadLibraryGetProcAddress 参见:msdn.microsoft.com/en-us/library/hh551132(v=vs.85).aspx 注意:“此函数没有关联的头文件”

标签: c++ winapi ntdll


【解决方案1】:

首先 - 你如何声明函数以及找不到链接器的符号?

声明必须是

extern "C" NTSYSAPI BOOLEAN NTAPI RtlIsNameInExpression(
                               _In_     PCUNICODE_STRING Expression,
                               _In_     PCUNICODE_STRING Name,
                               _In_     BOOLEAN         IgnoreCase,
                               _In_opt_ PWCH            UpcaseTable
                               );

如果您从here 复制粘贴,我可以猜到您错过了NTAPI__stdacall 关键字。对于 x64 仅存在一种调用约定,但对于 x86,例如 __stdcall__cdecl 之间存在不同。这可以解释为什么在x64 中找到但在x86 中没有找到

什么错误给你链接器(不是编译器!)?未解析的外部符号 __imp__RtlIsNameInExpression ? (如果是,你真的忘记了__stdcall 设置)还是__imp__RtlIsNameInExpression@16?在这种情况下,您声明函数正确,但您的 ntdll.lib 不包含此符号。 (可能是你用旧的ntdll.lib 为 xp ? ) 只需搜索 __imp__RtlIsNameInExpression@16 字符串,就像在 ntdll[p].lib 中一样 - 找到了吗?如果没有,我猜你有旧 (xp) 版本的 ntdll。

【讨论】:

  • 就是这样!我错过了 NTAPI 和 NTSYSAPI,我没有注意到。谢谢!
  • @rosl - 来自 ntdll 的几乎所有函数都是 __stdcall(很少使用 __fastcall)还请注意,前 2 个参数实际上是 PCUNICODE_STRING - 所以你可以传递给它并保持不变(只读)字符串 - 这是 nt-api 很常见的情况
  • 您没有使用 Winternl.h 标头吗?
  • @AdrianMcCarthy - 不,我个人不使用winternl.h。我更喜欢在自己的代码中包含ntifs.h(如果将其包含在命名空间中,则可以这样做)。但是无论如何RtlIsNameInExpression 甚至在winternl.h 中都没有声明 - 所以需要自己声明
【解决方案2】:

该功能的答案在在线documentation

此函数没有关联的头文件。 Microsoft Windows Driver Kit (WDK) 中提供了关联的导入库 Ntdll.lib。您也可以使用 LoadLibrary 和 GetProcAddress 函数调用此函数以动态链接到 Ntdll.dll。

如果无法将 WDK 中的 ntdll.lib 文件添加到链接命令中,则需要使用 LoadLibrary-GetProcAddress 方法。

也来自文档的同一部分:

Winternl.h 中的功能和结构是操作系统内部的,可能会从一个版本的 Windows 更改到下一个版本,甚至可能在每个版本的服务包之间发生变化。为了保持应用程序的兼容性,您应该改用等效的公共函数。头文件 Winternl.h 和每个函数的文档中提供了更多信息。

【讨论】:

  • 我添加了库。但不知何故,它适用于 64 位,但不适用于 32 位。
  • 您说“它以某种方式在 64 位上工作,但在 32 位上不工作。”好的,但它究竟是如何在 32 位上不起作用的呢?您是否从 GetProcAddress 得到一个 NULL 函数指针?该函数是否返回 FALSE?你的电脑会炸吗?什么?
猜你喜欢
  • 2014-07-31
  • 2011-04-20
  • 2012-04-06
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 2010-12-18
  • 1970-01-01
相关资源
最近更新 更多