Windows API

Windows API（ウィンドウズ エーピーアイ）とは、Microsoft Windowsのシステムコール用APIのこと。特に32ビットプロセッサで動作するWindows 95以降やWindows NTで利用できるものはWin32 APIと呼ばれる。また、それらのWindowsにおけるWin32 APIの実装をWin32と呼ぶ。 64ビットプロセッサ向けのWin64 APIも含める場合は「Windows API」という包括的な名称が正確だが、慣習的にWin32と言えばWin64も含んでいることがある。 Windows上で動作するアプリケーションにとって、Windows APIはWindowsの各機能にアクセスするための接点である。そのため、Windows上で動作するアプリケーションを作成できる様々なプログラミング言語・開発環境においてWindows APIを使用する手段が提供されている。特にCとC++向けには、Windows SDKにより、<windows.h>をはじめとする多数のヘッダーファイルが公開されている。また、多くの開発環境で、Windows APIを基にした、より高水準のフレームワークが構築されている。これらを通じて、すべてのWindowsアプリケーションは、直接的または間接的にWindows APIを使用している。 Windows APIに属する各APIは、主にDLLに実装されており、C言語形式関数またはCOMインターフェイスとして機能が公開されている。関数の呼出規約はWin32 (x86) の場合に原則としてstdcallを採用するなど、統一されたインターフェイスで多数のプログラミング言語からの使用を容易なものとしている。 Windows APIの中核となる機能はKernel、User、GDIに分けられる。当初は、それぞれKERNEL.EXE (モードによってはKRNL286.EXE、KRNL386.EXE)、USER.EXE、GDI.EXEに実装されていた。32ビット化されて以降は、KERNEL32.DLL、USER32.DLL、GDI32.DLLに実装されている。Windows 7の新カーネル、MinWinでは、"Virtual DLL"の仕組みが導入され、インターフェイス互換性を維持したうえで実装の整理が行なわれている。 Kernel ファイルシステム、デバイス、プロセス、スレッド、レジストリ、例外処理など基盤となる機能 User ウィンドウの処理、ボタンやスクロールバーなどといった基本的なコントロール、マウス・キーボード入力、その他グラフィカルユーザーインターフェイス (GUI) に関わる機能。 GDI ディスプレイ・プリンタをはじめとした出力装置への描画機能 現在では、これだけに留まらず、多数のDLLから無数の機能が公開されている。現在、マイクロソフトのドキュメントでは次のように分類している。 Administration and Management Diagnostics Graphics and Multimedia Networking Security System Services Windows User Interface なお、この分類では、KernelはDiagnosticsとSystem ServicesそしてSecurityに跨って属し、UserはWindows User Interface、GDIはGraphics and Multimediaに属する。 マイクロソフトはWindows 95/Windows NT 4以降、全てのWindowsにDirectXを用意している。DirectXは主にゲームとマルチメディアのためのAPIであるが、Windows Vista以降はDirectX GraphicsがGDIに代わってOSのグラフィックス描画の基盤として昇格されている。DirectX APIのうちのいくつかは、ゲームコンソールであるXbox、Xbox 360、Xbox Oneと共通になっている。 Direct3D OpenGLの置き換えとして3D グラフィックスアクセラレータの操作。 DirectDraw 2D グラフィックスアクセラレータの操作。DirectX 8.0以降、DirectDrawの機能はDirect3Dに吸収された。 DirectX Graphics DirectX 8.0以降に導入された名称で、Direct3DおよびDirectDrawの統合を意味するものだったが、DirectX 11以降はDXGI/Direct3D/Direct2D/DirectWrite/DirectCompositionの総称となっている。 DXGI (DirectX Graphics Infrastructure) Direct3D 10以降、DirectX Graphicsから比較的変化の緩やかな部分はDXGIとしてDirect3Dから分離された。 Direct2D Direct3D上に構築された高レベル2D描画用API。GDI+の置き換えとなる。 DirectWrite テキストおよびフォント／フォントグリフを扱う。 DirectSound 低水準なハードウェア（主にサウンドカード）への操作。 DirectMusic（英語版） DirectSoundの上位に位置し、音楽（メディアファイルの再生など）を扱う。 DirectX Audio DirectX 8.0以降に導入された名称で、DirectSoundおよびDirectMusicの統合を意味するものだったが、DirectX 9以降はX3DAudio/XAudio2/XACT/DirectSoundなどの総称となっている。 DirectInput ジョイパッドやゲームパッドからの入力、およびフォースフィードバックを扱う。 XInput Xbox 360コントローラーをWindows上で使えるようにするAPI。 DirectPlay（英語版） ネットワークなどを介した通信。 DirectShow 汎用的なマルチメディアパイプラインシステム。 DirectX APIはWindows APIの中でも変化が激しいAPIのひとつで、Direct3D RM、DirectDraw、DirectSound、DirectInput、DirectPlay、およびDirectMusicはWindows Vista以降完全な互換機能が用意されず、一部を除いて廃止あるいは代替APIに吸収されている。 Windows Imaging Component (WIC) Video for Windows、Media Control Interface（英語版） (MCI) やWinMMなどのWindowsマルチメディアAPI DirectShow Media Foundation Core Audio WGL（英語版） OpenGLとWindows (GDI) との連携部分を担当するAPIである。各関数名は接頭辞wglで始まり、<wingdi.h>で宣言されている。なお、Windows SDKに付属するOpenGLヘッダーおよびライブラリにはOpenGL 1.1までの関数しか定義されておらず、したがってOpenGL 1.2以降の機能を使うためには、Khronosから最新のOpenGLヘッダーをダウンロードしたのち、WGLのwglGetProcAddress()関数を用いてハードウェアベンダーが提供するOpenGL ICD (Installable Client Driver) の関数エントリポイントをアプリケーション実行時に取得するなどの作業が必要となる。 Winsock NetBIOS MSRPC Trident: IEコンポーネント (MSHTML) MSXML（英語版） WinINet Windows HTTP Services (WinHTTP) Component Object Model (COM) Microsoft Transaction Server (MTS), Distributed Component Object Model (DCOM) Object Linking and Embedding (OLE), ActiveX, OLEオートメーション ネイティブAPIは、Windows NT系においてWindows APIより下位層のAPIである。NT系では、NTネイティブAPI上にサブシステムとしてWin32 APIが実装されている。ただし、DirectXやGDIなどは、ネイティブAPIを介せずに、より下位に位置するカーネルと直接やり取りを行う。 Windowsで動作する.NET Frameworkは、基本的にWin32 APIを用いて実装されている。例えばWindows FormsおよびWindows Presentation Foundation (WPF) はそれぞれGDI/GDI+あるいはDirect3Dを利用したGUIアプリケーションのフレームワークであり、Win32 APIとの相互運用性も確保されている。 かつて、「Windows Vista以降、WinFXと呼ばれる新しいAPIがWindows APIに代わってネイティブAPIになる（WinFXが最も低水準なAPIとなりWindows APIはそのラッパーとなる）」とアナウンスされたことがあったが、結局撤回され、Windows Vista製品版では従来通りWindows APIがネイティブなAPIとなっている。WinFXの計画は方針転換され、予定されていた機能は.NET Framework 3.0としてリリースされた。 Windows APIは名前からも類推できるとおり、主にMicrosoft Windowsに実装されている。その実装はWindowsのバージョン毎に少なからず違いが存在する。たとえばWin32の場合、Win32c、Win32sではごく一部を除きUnicodeに対応していない、セキュリティ対策のアクセス制限が実装されていないなどといった違いが挙げられる。そしてそれは大きく次のように分類することができる。 Win16は、16ビットプログラム用の実装である。ただし、Win16という語自体はWin32が登場してから用いられるようになったレトロニムである。Win16は大きく2種類に分けられる。 Windows 1.0からWindows 3.1までおよびWindows 95/98/Me（9x系）の実装。 WOW (Windows on Windows): Windows NTによるWin16サブシステムによる実装。 Win32は、32ビットプログラム用の実装である。次のように分けられる。 Win32 狭義のWin32は、NT系の実装を指す。 Win32c 9x系の実装。'c'は「compatibility」（互換）の頭文字である。しかし、現在[いつ?]では9xの実装も区別なくWin32と呼ぶ。 Win32s Windows 3.1用の実装。's'は「subset」（サブセット）の頭文字である。Windows 3.1には搭載されておらず、別途入手・インストールする必要がある。 Win32 for Windows CE Windows CEの実装。文字コードにUnicodeのみを使用するなどの点が特徴的である。 WOW64 (Windows on Windows 64) Win64上でWin32をエミュレーションするサブシステムによる実装。 Windows NTがx86以外のアーキテクチャに移植されたことに伴い、Win32は各種アーキテクチャ向けに移植されている。また、Windows NTではないが、かつてMacintosh用のWin32も存在し、Microsoft Visual C++ 4.0 Cross-Development Edition for Macintoshとしてクロスコンパイラとともに発売されていた。これらアーキテクチャの異なるWin32の間にはソースコード上での互換性がある。 Win64は、64ビットプログラム用の実装である。2021年3月現在の主流はx64だが、Windows 10ではARM64もサポートされるようになった。 かつてWindows Server 2003およびWindows XPにてIA-64のサポートが始まったが、Windows Server 2008 R2を最後にサポートが打ち切られた。 Windows APIの仕様はWindows SDKのドキュメントやMicrosoft Docs（旧MSDN ライブラリ）で公開されており、それを基にしたMicrosoft Windows以外のWindows APIの実装が存在する。 Wine ReactOS HX DOS Extender WindowsランタイムAPI (WinRT API) は、Windows 8で導入されたWindowsストアアプリ (Modern UIアプリケーション) を開発するためのCOM拡張による高レベルAPI。後継となるWindows 10で導入されたユニバーサルWindowsプラットフォーム (UWP) アプリケーションの開発におけるベースAPIにもなっている。一部のWinRT APIは、従来のデスクトップアプリケーションから利用することもできる。従来のWindows APIは、WinRT APIと対比・区別されるとき、Win32 APIと呼ばれることが多い。 Windows NT系では当初からUnicodeが用いられている一方、Unicodeに対応していないWin16と互換性を取るために、Win32 APIから同じAPIに対してマルチバイト文字版とUnicode版の2つを用意し、C/C++のマクロを駆使してコンパイル時にどちらを使うか選択できる仕組みが採用されている。なお、Unicodeの符号化には当初UCS-2が、Windows 2000から正式にUTF-16が用いられている。 具体的には、文字および文字列の関わる関数・構造体について、マルチバイト文字（Windowsコードページに基づく、日本語環境であればコードページ932）とUnicode (UTF-16) のどちらを与えることもできるように、2つの関数・構造体などが準備されている。その場合、マルチバイト文字列を与えるべき関数・構造体は末尾に「A」を付け、ワイド文字列を与えるべき関数・構造体は末尾に「W」を付けて区別している。例えば、Win16のMessageBox関数に対して、Win32ではMessageBoxAとMessageBoxWという2つの関数が用意されている。そして、プリプロセッサ識別子UNICODEの定義の有無によって切り替えが行われる。 #ifdef UNICODE #define MessageBox MessageBoxW #else #define MessageBox MessageBoxA #endif さらに、文字型に対しても同様にCHAR (charのtypedef) とWCHAR (wchar_tのtypedef) をUNICODEの定義に応じて切り替えるTCHAR型などや、ナロー文字列定数・リテラルとワイド文字列定数・リテラルを切り替えるTEXTマクロが存在する。 #ifdef UNICODE #define TEXT(s) L ## s typedef WCHAR TCHAR; #else #define TEXT(s) s typedef CHAR TCHAR; #endif これらを適切に用いると、1つのソースコードからコンパイル時のオプションによってマルチバイト文字を用いる実行プログラムとワイド文字を用いる実行プログラムの2種類が作成できる。以下はその例である。 #include <windows.h> #include <tchar.h> // WinMain と wWinMain を切り替える _tWinMain などが定義されている。 int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE hInstPrev, LPTSTR lpszCommandLine, int nCmdShow) { MessageBox(NULL, TEXT("Hello, world"), TEXT("App"), MB_OK); return 0; } なお、Windows NT系におけるA版のAPI関数は、内部的にW版を呼び出すラッパーとなっている。A版APIに入力されたマルチバイト文字列はUnicode文字列に変換されてからW版APIに入力され、W版APIから出力されたUnicode文字列はマルチバイト文字列に変換されてA版APIの出力となる。 このプレフィックスのAはANSI、WはWideを意味する。ANSIは、Windowsコードページの一部がANSI規格のドラフトを元にしたことに由来する。ワイド文字 (wchar_t) はC/C++の用語であるが、Windows用のC/C++処理系において、ワイド文字は大抵UCS-2またはUTF-16として実装されている。また、OLE関係では、Win32ですべてUnicode化され、A/Wの区別が存在しない。 なお、Windows 9x系では、Unicode版APIは一部しか実装されていない。ただし、Microsoft Layer for Unicodeを利用することにより、ほぼすべてのUnicode版APIが使用可能になる。また、Windows CEでは、逆にUnicode版APIしか実装していない。NT系でも、Unicodeを前提とした仕様変更が行われたり、Theme APIなど新しいAPIでA/Wの2種を用意せずUnicodeを用いるものだけを用意したりするなど、徐々にUnicodeへ傾斜する傾向にある。 Windows APIの歴史は、もちろんWindows自体の歴史と切り離せない関係にある。常に、Windowsに新機能が搭載されれば、それをアプリケーションソフトウェアから使用するための新しいAPIが追加され、対応する新しいSDKが公開されることの繰り返しである。デバイスドライバーに対応を迫るものは、DDK/WDK経由で公開される。 Windows APIの歴史上、最も大きな変革はWindows NTに伴うWin32の登場だった。ポインタとハンドルも32ビット化されたこと、Unicodeへの対応が図られたことが大きな変化である。 なお、現在[いつ?]は緩やかに64ビットへの移行が進んでいる。Win64では、ポインタおよびハンドルは64ビット化されているが、それ以外では16ビットから32ビットへの移行時のような大きな変化はない。なお、64ビット版Windowsでは32ビットアプリケーションとの相互運用性を確保するため、ハンドルの上位32ビットを使用する仕組みとなっており、ウィンドウ (HWND) などのユーザーオブジェクトハンドル、ブラシ (HBRUSH) やペン (HPEN) などのGDIオブジェクトハンドル、そしてミューテックス、セマフォ、ファイルなどの名前付きオブジェクトハンドルを32ビット/64ビットアプリケーション間で共有し、プロセス間通信に利用することができる。また、64ビット版WindowsではWOW64により32ビットアプリケーションを実行できるが、16ビットアプリケーションを実行することはできない。 Windows APIはシステム全体で共有するDLLを通じて公開されており、このシステムDLLに変更が入るとすべてのアプリケーションが影響を受けることになる。このため、度重なるバージョンアップやセキュリティパッチの適用によりコンポーネントの互換性を失ってしまうことによるDLL地獄 (DLL Hell) の発生を招くことがある。この点に関しては、Windows 2000で導入されたSide-by-Sideコンポーネント共有や、Windows XPで導入された分離アプリケーションとSide-by-Sideアセンブリの仕組みにより、ある程度の解決が図られている。 基本的にWindowsおよびWindows API自体は互換性に配慮した設計がなされており、バージョンアップの際に既存の公開APIに破壊的変更が入ることはない（時代遅れとなった古いAPIが非推奨になることはあるが、完全に削除されることはまれである）。公開APIを正しく利用して開発されたアプリケーションやドライバーであれば、旧バージョンのOSで正常に動作していたものは、ほとんどのケースにおいて修正することなく動作する。セキュリティ対策のためにWindows Vistaで導入されたユーザーアカウント制御 (UAC) に関しても、通常権限のアプリケーションが直接アクセスできないディレクトリに対する読み書きを仮想化してリダイレクトする仕組みが救済策として用意されている。しかし、アプリケーションやドライバーが特定のバージョンのWindowsでしか動かないような設計になっていた場合、アプリケーションが起動できない、正常に動作しないなどの互換性問題が発生することがある。この問題の回避策のひとつとして、Windowsには、旧バージョンのOSの動作をある程度エミュレートする「互換モード」が用意されている。例えばバージョン番号を取得するためのWindows APIにおいて旧バージョンのOSを偽装した値を返すようにすることで、これらに依存したアプリケーションへの影響を低減する。 Windows APIはWin16を拡張して32ビット、64ビット化されたという歴史がある。そのため度重なる機能の追加により、高度に複雑化しその習得が困難と化しているという問題がある。 Windows 8で導入された新規設計のWinRT APIは、名前空間を利用して体系的に整理されており、効率的かつモダンなアプリケーション開発をサポートするが、Windowsストアアプリ（のちのUWPアプリ）はサンドボックス環境で動作するために制約が多く、サードパーティー開発の主流とはならなかった。結局は従来のWin32 APIや.NET Frameworkを使用したデスクトップアプリケーションが主流のままであるが、Win32 APIによる開発はGUIツールキットのサポートが弱く、レガシーな外観のGUIウィジェットしか使えないなどの問題がある。 Windows APIは比較的低水準であるため、高水準なインターフェイスを持たせたり、C/C++以外の言語から利用したりするための様々なラッパーライブラリやフレームワークが数多く存在する。主なものは次のとおり。 Microsoft Foundation Class (MFC) C++クラスによるWindows APIのラッパー。 Active Template Library (ATL) C++テンプレートによるCOMのラッパー。 Windows Template Library (WTL) ATLの拡張として作られた軽量のWindows APIのラッパー。現在[いつ?]はCPLに基づくオープンソースとなっている。 Object Windows Library (OWL) MFCと同時期に公開され、よりオブジェクト指向に作られたラッパー。 Visual Component Library (VCL) ボーランドがその後に開発したDelphiによるラッパー。Windows Formsのベースにもなった。 .NET FrameworkやWindows版.NET Coreは、内部的にWindows APIを利用して実装されているものの、基本クラスライブラリなどはプラットフォーム非依存となるよう抽象化されているが、Windows固有の機能を使用したGUIフレームワークや、Windows APIを薄くラップしただけの部分も存在し、System.Windows名前空間やMicrosoft.Win32名前空間などにまとめられている。