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の場合は必ず確認しよう。