【问题标题】:64bit windows api programming type casting problem64bit windows api编程类型转换问题
【发布时间】:2020-02-09 15:29:38
【问题描述】:

(对不起,我的英语不好)。我有 2 个关于 64 位 c 编程的问题。

我的代码运行良好,但今天出现错误(没有编译器或代码分析)。而且是随机的。例如,有时代码有效,有时无效。当我在 WinDbg 中打开可执行文件时,我的代码总是出错。我认为它的 64 位类型转换问题。

代码示例:

DWORD hash_string_len = 0;
hash_string_len = (DWORD)strlen(hash_string); //hash_string is 32 character hash (A998B0FE08AB295072965B5A4B0C835E)
if (hash_string_len != (DWORD)(MD5_DIGEST_LENGTH * 2)) //MD5_DIGEST_LENGTH (#define MD5_DIGEST_LENGTH 16)
{
   debug_this(); //printf("%d\n",__LINE__)
   HeapFree(GetProcessHeap(), 0, ENGINE_HASHLIST_MD5_ENTRY);
   return FALSE;
}

没有 WinDbg 代码不打印错误(通过 debug_this())但在 WinDbg 代码中打印行号(原因是 hash_string_len != 32)但我知道 hash_string_len = 32 所以我认为它的 64 位截断问题。有人可以帮帮我吗?

我的第二个问题是:

它会在 64 位编程中给我错误吗?

DWORD a = 0;

some_func(&a);


some_func(PDWORD pA)
{
 *pA = 1;
}

因为我在我的项目中使用了很多这样的代码。就这样。

LZMA 库

SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);

我这样称呼这个函数。

DWORD destLen = 0;
PBYTE dest = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(SIZE_T)1024);
LzmaDec_DecodeToBuf(...,dest,&destLen,...)

所以我在 64 位编程中确实存在功能问题。感谢阅读

【问题讨论】:

  • 在您的具体代码片段中没有任何错误。并且与 64 位特定的无关
  • @RbMm: "* 没有任何错误*" 好吧,没有。请参阅my answer
  • @alk - 是的,不是不专心看最后一个代码片段。基于秒 - 其中some_funcDWORD 作为参数。 if 函数 (LzmaDec_DecodeToBuf) 将 size_t* 作为参数 - 当然这里错误传递指针到 DWORD

标签: c visual-studio winapi 64-bit


【解决方案1】:

假设SizeTSIZE_T

我这样称呼这个函数。

DWORD destLen = 0;
PBYTE dest = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(SIZE_T)1024);
LzmaDec_DecodeToBuf(...,dest,&destLen,...)

将 DWORD 的地址(在 32 位窗口和 64 位窗口上为 32 位宽)传递到 SIZE_T 的地址(在 64 位窗口上为 64 位宽,在 32 位窗口上为 32 位宽) -bit-windows) 是错误的。

DWORD 转换为SIZE_T 在获取其地址之前,如下所示:

LzmaDec_DecodeToBuf(..., dest, &((SIZE_T) destLen), ...)

引入SIZE_T的临时变量并传递其地址:

{
  SIZE_T s = destLen; /* The initialisation is only necessary if
                         LzmaDec_DecodeToBuf() expects a value. */
  LzmaDec_DecodeToBuf(..., dest, &s, ...);
  if (((SIZE_T) UINT_MAX) < s) {
    /* handle overflow of destLen! */
  }
  destLen = s;
}

更多关于在 Windows 上使用 VC 将代码从 32 位迁移到 64 位的问题在这里:https://docs.microsoft.com/en-us/cpp/build/common-visual-cpp-64-bit-migration-issues?view=vs-2019

【讨论】:

  • 要么我误解了你,要么你的建议具有误导性:不是将destLen 变量的类型从DWORD 更改为SIZE_T,而是执行显式转换。但是该变量仍然是 32 位长,并且在尝试将 64 位值写入传递的地址时会溢出。我建议每个 64 位软件开发人员阅读以下指南:development of 64-bit C and C++ applications
猜你喜欢
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
  • 2012-10-01
  • 2010-12-29
  • 1970-01-01
相关资源
最近更新 更多