【问题标题】:Issue in porting application from 32bit to 64bit将应用程序从 32 位移植到 64 位的问题
【发布时间】:2020-10-28 19:36:02
【问题描述】:

以下代码作为 32 位应用程序运行良好。(在 gcc 4.6.3 上编译),我将相同的代码移植到 64 位应用程序,它没有给出正确的输出。

#include <iostream>
#include <stdint.h>
using namespace std;
typedef unsigned long DWORD;
typedef unsigned long long int  uint64;
typedef long long LONGLONG;
typedef struct _SND_FILETIME
{
    DWORD dwLowDateTime;
    DWORD dwHighDateTime;
} SND_FILETIME, *SND_PFILETIME, *SND_LPFILETIME;

void FileTimeToUnixTime(const SND_FILETIME *pft, time_t *t)
{
#if BYTE_ORDER == LITTLE_ENDIAN
        LONGLONG ll = (LONGLONG)pft->dwHighDateTime;
        ll <<= 32;
        ll |= (LONGLONG)pft->dwLowDateTime;
#else
        LONGLONG ll = (LONGLONG)pft->dwLowDateTime;
        ll <<= 32;
        ll |= (LONGLONG)pft->dwHighDateTime;
#endif
        ll -= 116444736000000000LL;
        ll /= 10000000;
        *t = (time_t)ll;
        struct tm *info = localtime(t);
       cout << "Time" << asctime(info) << std::endl;
}
int main()
{
    uint64 time64 = 132385716359962190;
    SND_FILETIME* ptr = (SND_FILETIME*)&time64;
    cout <<"HighPart = " << ptr->dwHighDateTime <<endl;
    cout <<"lowPart = " << ptr->dwLowDateTime <<endl;
    time_t t;
    FileTimeToUnixTime(ptr,&t);
    return 0;
}

我为 32 位应用程序获得的输出:

高部分 = 30823451 低部分 = 2365103694 时间2020年7月7日星期二10:30:35

对于 64 位应用程序: 高部分 = 140730490267024 低部分 = 132385716359962190 时间8月11日星期二02:12:08 23514

如果我将输入更改为类似,

uint64 time64 = 132385716359962190;
    SND_FILETIME filetime;
    filetime.dwHighDateTime = 0;
    filetime.dwLowDateTime = 132385716359962190;
    SND_FILETIME* ptr=&filetime;
   
    cout <<"HighPart = " << ptr->dwHighDateTime <<endl;
    cout <<"lowPart = " << ptr->dwLowDateTime <<endl;
    time_t t;
    FileTimeToUnixTime(ptr,&t);

64 位应用程序有效。但我不想这样做,因为我必须更改所有代码。有什么方法可以在不更改代码的情况下完成这项工作。

请帮忙!!!

谢谢,

【问题讨论】:

  • SND_FILETIME* ptr = (SND_FILETIME*)&amp;time64; 是未定义的行为。您不能将一种类型重新解释为另一种类型(除非任何一种类型是某种 char 或 std::byte 类型,如果目标是类类型则有更多限制)。因此,建议您如何似乎修复错误的设计是没有意义的。您应该改为手动从 int 中解析/复制这些位。 (如果你想继续写UB,你至少应该检查DWORD的大小是否相同,但请不要保留UB。)
  • 由于您的代码显然取决于精确的整数大小,我建议您放弃 long 并在所有地方使用您所指的大小,即 uint64_t、uint32_t、int64_t 和 @ 987654332@。你包括stdint.h,所以使用它。顺便说一句,您的代码在 32 位和 64 位版本中都适用于我使用 VC++。所以它应该很容易修复。
  • 与您的问题无关,但任何以下划线开头并后跟大写字母的符号(例如_SND_FILETIME)都保留在 all 范围内。参见例如this 了解更多详情。
  • 是的,你抓住了我 :) ,实际应用程序也很大,由于时间紧迫,我需要更快地做到这一点。
  • 代码中充满了宏的东西,没有使用 STL (uint_xx) 中定义的任何类型,并且在命名约定中使用类型,对内存布局的假设......很多需要返工!

标签: c++ linux 32bit-64bit porting


【解决方案1】:

将DWORD的typedef改成:

typedef unsigned int DWORD;

另外,将uint64 更新为属于stdint.h 标头的uint64_t。

【讨论】:

    猜你喜欢
    • 2011-04-03
    • 1970-01-01
    • 2010-12-18
    • 2011-03-11
    • 2014-12-05
    • 1970-01-01
    • 2018-02-17
    • 2017-12-11
    • 1970-01-01
    相关资源
    最近更新 更多