FILETIMEの変換方法

[戻る]
KIN 2006/10/10(火) 17:25:48
いつもお世話になっております。
初めて質問させて頂きます。
開発環境は、WinXP Pro(SP2) + VC++6.0(SP6)です。

現在以下のようなことを行うプログラムを考えています。

・現在時刻を取得(GetLocalTime)
・FILETIMEに変換(SystemTimeToFileTime)
・FILETIMEをUINT64(unsigned __int64)変換 ※1
・現在時刻+1秒の値を取得するため、UINT64型の値に +10000000
・UINT64からFILETIMEに変換 ※2
・FILETIMEからSYSTEMTIMEに変換


※1、2の変換においてどの方法が適切なのか悩んでいます。

UINT64 ull;
FILETIME ft;

※1の変換方法
方法1:ull = *( UINT64* )&ft;
方法2:ull = ft.dwHighDateTime;
       ull = ull<<32;
       ull = ull + ft.dwLowDateTime;
方法3:CopyMemory(&ull, &ft, sizeof(FILETIME));

※2の変換方法
方法1:ft = *( FILETIME* )&ull;
方法2:CopyMemory(&ft, &ull, sizeof(FILETIME));

いろいろなサイトを参考にさせてもらったのですが、
どの方法でも演算は可能ですが、最適なものがどれなのか
逆にわからなくなってしまいました。


何か、アドバイスがあれば教えてください。
よろしくお願いいたします。

Blue 2006/10/10(火) 17:40:41
どれもありだと思う。

>最適なものがどれなのか
何を持って最適とするかによります。(見易さ?速度?)

>ull = ft.dwHighDateTime;
>ull = ull<<32;
>ull = ull + ft.dwLowDateTime;
MAKELONGみたいなマクロ(MAKEUINT64)を作ってあげるとすっきりしそう。

>※2の変換方法
もLOUINT64,HIUINT64てなマクロもありかな。


# MAKELONGとかMAKEWORDとかあるってことは、そういうやり方が一番なんだろうかな
ぁ。

tetrapod 2006/10/10(火) 21:21:09
MSDN には ULARGE_INTEGER に変換してから演算しろと書いてあるっす
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/sysinfo/base/filetime_str.asp
どうせバリバリにWindows依存なんだからどの方法でもいいと思うけど
union u_calculatable_time {
  ULARGE_INTEGER ulval;
  FILETIME ft;
};
とか。必要に応じて operator を実装しておくとより便利。

KIN 2006/10/11(水) 13:43:24
[[解決]]
Blueさん、tetrapodさん、レスありがとうございます。

>MAKELONGみたいなマクロ(MAKEUINT64)を作ってあげるとすっきりしそう。
>もLOUINT64,HIUINT64てなマクロもありかな。

FILETIMEとの関係を考え、見よう見まねで以下のようなマクロを組んでみました。

#define MAKEUINT64(low, high) ((UINT64)(((DWORD)(low)) | ((UINT64)((DWORD)
(high))) << 32))
#define HIDWORD(high) ((DWORD) (((UINT64) (high) >> 32) & 0xFFFFFFFF))
#define LODWORD(low) ((DWORD)(low))


>union u_calculatable_time {
>  ULARGE_INTEGER ulval;
>  FILETIME ft;
>};

MSDNはみたのですが、ULARGE_INTEGERへの変換方法がよくわからなかったんですよね。
なるほど、このような使い方をすれば確かに便利ですね。


>何を持って最適とするかによります。(見易さ?速度?)
確かにそうですね。

とりあえず、教えていただいた方法含め、少し考えてみたいと思います。
アドバイスありがとうございました。

tetrapod 2006/10/11(水) 14:27:42
ULARGE_INTEGER に変換できたなら QuadPart に対して演算したらいいので
その種の MAKE** マクロ系はみな不要なわけだ

union myftime {
    FILETIME ft;
    ULARGE_INTEGER ul;
    // 64bit add with raw-value
    myftime& operator+=(__int64 n) { ul.QuadPart+=n; return *this; }
};

operator FILETIME*() { return &ft; }
なんてのも実装すると(混乱の元になるのは確実だが)
myftime f1; GetFileTime(h, f1, 0, 0); って使い方もできたりとかする。

前者の operator+= の実装はお勧め
後者の operator FILETIME* の実装は非推奨
だろうね。

古いスレッドには追加発言できません。