最近、LARGE_INTEGERやULARGE_INTEGERといった型を見かけることが増えてきた。これらはGetDiskFreeSpaceExなど大きな数値を扱うAPIを中心に使われている。この型がどのように定義されているのかを見てみると、以下のようになっていた。
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
};
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER;
typedef LARGE_INTEGER *PLARGE_INTEGER;
typedef union _ULARGE_INTEGER {
struct {
DWORD LowPart;
DWORD HighPart;
};
struct {
DWORD LowPart;
DWORD HighPart;
} u;
ULONGLONG QuadPart;
} ULARGE_INTEGER;
typedef ULARGE_INTEGER *PULARGE_INTEGER;
つまりLARGE_INTEGER=LONGLONG、ULARGE_INTEGER=ULONGLONGということがわかる。すなわちLARGE_INTEGERは符号付の数値型で、ULARGE_INTEGERは符号なしの数値型ということになる。
LONGLONGやULONGLONG型は普段よく目にする4bytesの大きさのLONGやULONG、DWORD型の2倍で8bytesもの大きさがある。大きすぎて扱いづらいため上位ダブルワードをHighPart、下位ダブルワードをLowPart、全体をQuadPartとして定義されている。
そのためプログラムで使うときには以下のようにできる。
依存環境:ATL#include "atlstr.h"
void Test(void)
{
LARGE_INTEGER lnTest;
CAtlString strMessage;
int nSize = sizeof(LARGE_INTEGER); // nSize == 8bytes
lnTest.QuadPart = -1;
strMessage.Format(_T(" sizeof(LARGE_INTEGER) = %d \n HighPart = %X \n LowPart = %X \n QuadPart = %I64X \n QuadPart(signed) = %I64d \n QuadPart(unsigned) = %I64u"),nSize,lnTest.HighPart,lnTest.LowPart,lnTest.QuadPart,lnTest.QuadPart,lnTest.QuadPart);
::MessageBox(NULL,strMessage,_T(""),MB_OK);
lnTest.HighPart = 1;
lnTest.LowPart = 2;
strMessage.Format(_T(" sizeof(LARGE_INTEGER) = %d \n HighPart = %X \n LowPart = %X \n QuadPart = %I64X \n QuadPart(signed) = %I64d \n QuadPart(unsigned) = %I64u"),nSize,lnTest.HighPart,lnTest.LowPart,lnTest.QuadPart,lnTest.QuadPart,lnTest.QuadPart);
::MessageBox(NULL,strMessage,_T(""),MB_OK);
}
プロジェクトファイルをダウンロード


要はLARGE_INTEGER(ULARGE_INTEGER)に数値を代入したいときはQuadPartに代入すればいい。もしも上位ダブルワードと下位ダブルワードを区別して代入したいときはそれぞれHighPartとLowPartを利用する。
ただしprintfやsprintf、TRACE、CString::Formatなどの関数で数値から文字列に変換したい場合は注意が必要だ。
QuadPartは8bytes(64bits)もの大きさがある。そのためprintf("%d",xx.QuadPart);のように「%d」や「%x」を利用することはできない。64bitsを処理できるように「%I64d」や「%I64x」のように「I64」指定をしなければいけない。
