【发布时间】: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*)&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