![]()
MSDNライブラリを見ていると新しいOSやサービスパック、Internet ExplorerがリリースされるたびにAPIなどが増えていることに気づく。
例えばWindows XPから追加されたものの1つのGetNativeSystemInfoというのがある。これはCPUの数などのシステム情報を取得するためのAPIだ。MSDNには左の図のように掲載されている。
ここで赤く囲んだところが注意すべきところだ。このAPIの場合はWindows XP、Vista、Windows 2003 Serverなどに対応していることが分かる。
実際にこのAPIを利用して簡単なテストプログラムを作ってみる。搭載されているCPU数を取得して表示するだけの簡単なものだ。
#include "atlstr.h"
void Test(void)
{
CAtlString strMessage;
SYSTEM_INFO sInfo;
::GetNativeSystemInfo(&sInfo);
strMessage.Format(_T("CPU(コア)は %d 個"),sInfo.dwNumberOfProcessors);
::MessageBox(NULL,strMessage,_T(""),MB_OK);
}
プロジェクトファイルをダウンロード
私のパソコンはCPUにCore Duoが使われているのでコア数が2個。そのためWindows XP環境で実行するとこのように表示された。
次に作成した実行ファイルをWindows 2000へコピーして実行してみた。すると...
このようなエラーメッセージが表示されて実行できなかった。
作成したプログラムの中に1つでも対応OSがWindows XP以降のAPIが含まれていた場合、そのプログラムはWindows 2000では起動もしなくなってしまう。これが対応OSに注意を払わなければいけない理由だ。
ではどうすればWindows 2000でも起動するプログラムにできるかと言うと、LoadLibraryで使いたいAPIが実装されているDLLファイルを読み込み、GetProcAddressでそのAPIのアドレスを取得してAPIを実行する。そうすればAPIが対応していないOSの場合は、GetProcAddressに失敗するだけで起動しなくなるという問題は起きない。
GetNativeSystemInfoを例に具体的に書くと以下のようになる。
#include "atlstr.h"
//
// GetNativeSystemInfoラッパー関数
//
//GetNativeSystemInfoはWindows XP以降でサポートされている。
//そのためWindows 2000以前ではfalseが返る
//
bool SafeGetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo)
{
HMODULE hDLL;
void (CALLBACK* pfnGetNativeSystemInfo)(LPSYSTEM_INFO);
if(lpSystemInfo == NULL)
return false;
::ZeroMemory(lpSystemInfo,sizeof(SYSTEM_INFO));
hDLL = ::LoadLibrary(_T("Kernel32.dll"));
if(hDLL == NULL)
return false;
(*(FARPROC*)&pfnGetNativeSystemInfo) = ::GetProcAddress(hDLL,"GetNativeSystemInfo");
if(pfnGetNativeSystemInfo == NULL)
{
::FreeLibrary(hDLL);
return false;
}
pfnGetNativeSystemInfo(lpSystemInfo);
::FreeLibrary(hDLL);
return true;
}
void Test(void)
{
bool ret;
CAtlString strMessage;
SYSTEM_INFO sInfo;
ret = SafeGetNativeSystemInfo(&sInfo);
if(ret)
{
strMessage.Format(_T("CPU(コア)は %d 個"),sInfo.dwNumberOfProcessors);
::MessageBox(NULL,strMessage,_T(""),MB_OK);
}
else
::MessageBox(NULL,_T("取得に失敗しました。"),_T(""),MB_OK);
}
プロジェクトファイルをダウンロード
これでAPIが対応していないWindows 2000などで実行すると以下のようにプログラム中で実装したエラーメッセージが表示される。
1番上のMSDNライブラリ画像中の赤い枠で示した部分には対応OS以外にもLoadLibraryで利用するDLL名なども書かれている。普段はあまり目がいかないかもしれないが、かなり重要なデータだ。初めて実装に使うAPIの場合は必ず確認しよう。
