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も含んでいることがある。

1. 概要
-----

Windows上で動作するアプリケーションにとって、Windows APIはWindowsの各機能にアクセスするための接点である。そのため、Windows上で動作するアプリケーションを作成できる様々なプログラミング言語・開発環境においてWindows APIを使用する手段が提供されている。特にCとC++向けには、Windows SDKにより、をはじめとする多数のヘッダーファイルが公開されている。また、多くの開発環境で、Windows APIを基にした、より高水準のフレームワークが構築されている。これらを通じて、すべてのWindowsアプリケーションは、直接的または間接的にWindows APIを使用している。

Windows APIに属する各APIは、主にDLLに実装されており、C言語形式関数またはCOMインターフェイスとして機能が公開されている。関数の呼出規約はWin32  の場合に原則としてstdcallを採用するなど、統一されたインターフェイスで多数のプログラミング言語からの使用を容易なものとしている。

2. 分類
-----

Windows APIの中核となる機能はKernel、User、GDIに分けられる。当初は、それぞれKERNEL.EXE 、USER.EXE、GDI.EXEに実装されていた。32ビット化されて以降は、KERNEL32.DLL、USER32.DLL、GDI32.DLLに実装されている。Windows 7の新カーネル、MinWinでは、"Virtual DLL"の仕組みが導入され、インターフェイス互換性を維持したうえで実装の整理が行なわれている。

Kernelファイルシステム、デバイス、プロセス、スレッド、レジストリ、例外処理など基盤となる機能Userウィンドウの処理、ボタンやスクロールバーなどといった基本的なコントロール、マウス・キーボード入力、その他グラフィカルユーザーインターフェイス  に関わる機能。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に属する。

2.1. グラフィックとマルチメディア
-------------------

2.1.1. DirectX
--------------

マイクロソフトはWindows 95/Windows NT 4以降、全てのWindowsにDirectXを用意している。DirectXは主にゲームとマルチメディアのためのAPIであるが、Windows Vista以降はDirectX GraphicsがGDIに代わってOSのグラフィックス描画の基盤として昇格されている。DirectX APIのうちのいくつかは、ゲームコンソールであるXbox、Xbox 360、Xbox Oneと共通になっている。

Direct3DOpenGLの置き換えとして3D グラフィックスアクセラレータの操作。DirectDraw2D グラフィックスアクセラレータの操作。DirectX 8.0以降、DirectDrawの機能はDirect3Dに吸収された。DirectX GraphicsDirectX 8.0以降に導入された名称で、Direct3DおよびDirectDrawの統合を意味するものだったが、DirectX 11以降はDXGI/Direct3D/Direct2D/DirectWrite/DirectCompositionの総称となっている。DXGI Direct3D 10以降、DirectX Graphicsから比較的変化の緩やかな部分はDXGIとしてDirect3Dから分離された。Direct2DDirect3D上に構築された高レベル2D描画用API。GDI+の置き換えとなる。DirectWriteテキストおよびフォント／フォントグリフを扱う。DirectSound低水準なハードウェアへの操作。DirectSoundの上位に位置し、音楽を扱う。DirectX AudioDirectX 8.0以降に導入された名称で、DirectSoundおよびDirectMusicの統合を意味するものだったが、DirectX 9以降はX3DAudio/XAudio2/XACT/DirectSoundなどの総称となっている。DirectInputジョイパッドやゲームパッドからの入力、およびフォースフィードバックを扱う。XInputXbox 360コントローラーをWindows上で使えるようにするAPI。ネットワークなどを介した通信。DirectShow汎用的なマルチメディアパイプラインシステム。DirectX APIはWindows APIの中でも変化が激しいAPIのひとつで、Direct3D RM、DirectDraw、DirectSound、DirectInput、DirectPlay、およびDirectMusicはWindows Vista以降完全な互換機能が用意されず、一部を除いて廃止あるいは代替APIに吸収されている。

2.1.2. 静止画
----------

Windows Imaging Component 

2.1.3. 動画・音声
------------

Video for Windows、Media Control Interface  やWinMMなどのWindowsマルチメディアAPI
DirectShow
Media Foundation
Core Audio

2.1.4. OpenGL
-------------

OpenGLとWindows  との連携部分を担当するAPIである。各関数名は接頭辞wglで始まり、で宣言されている。なお、Windows SDKに付属するOpenGLヘッダーおよびライブラリにはOpenGL 1.1までの関数しか定義されておらず、したがってOpenGL 1.2以降の機能を使うためには、Khronosから最新のOpenGLヘッダーをダウンロードしたのち、WGLのwglGetProcAddress関数を用いてハードウェアベンダーが提供するOpenGL ICD  の関数エントリポイントをアプリケーション実行時に取得するなどの作業が必要となる。

2.2. ネットワーク・インターネット
-------------------

Winsock
NetBIOS
MSRPC
Trident: IEコンポーネント 
WinINet
Windows HTTP Services 

2.3. コンポーネント技術
--------------

Component Object Model 
Microsoft Transaction Server , Distributed Component Object Model 
Object Linking and Embedding , ActiveX, OLEオートメーション

2.4. ネイティブAPI
-------------

ネイティブAPIは、Windows NT系においてWindows APIより下位層のAPIである。NT系では、NTネイティブAPI上にサブシステムとしてWin32 APIが実装されている。ただし、DirectXやGDIなどは、ネイティブAPIを介せずに、より下位に位置するカーネルと直接やり取りを行う。

2.5. .NET Frameworkとの関係
-----------------------

Windowsで動作する.NET Frameworkは、基本的にWin32 APIを用いて実装されている。例えばWindows FormsおよびWindows Presentation Foundation  はそれぞれGDI/GDI+あるいはDirect3Dを利用したGUIアプリケーションのフレームワークであり、Win32 APIとの相互運用性も確保されている。

かつて、「Windows Vista以降、WinFXと呼ばれる新しいAPIがWindows APIに代わってネイティブAPIになる」とアナウンスされたことがあったが、結局撤回され、Windows Vista製品版では従来通りWindows APIがネイティブなAPIとなっている。WinFXの計画は方針転換され、予定されていた機能は.NET Framework 3.0としてリリースされた。

3. 実装
-----

Windows APIは名前からも類推できるとおり、主にMicrosoft Windowsに実装されている。その実装はWindowsのバージョン毎に少なからず違いが存在する。たとえばWin32の場合、Win32c、Win32sではごく一部を除きUnicodeに対応していない、セキュリティ対策のアクセス制限が実装されていないなどといった違いが挙げられる。そしてそれは大きく次のように分類することができる。

3.1. Win16
----------

Win16は、16ビットプログラム用の実装である。ただし、Win16という語自体はWin32が登場してから用いられるようになったレトロニムである。Win16は大きく2種類に分けられる。

Windows 1.0からWindows 3.1までおよびWindows 95/98/Meの実装。
WOW : Windows NTによるWin16サブシステムによる実装。

3.2. Win32
----------

Win32は、32ビットプログラム用の実装である。次のように分けられる。

Win32狭義のWin32は、NT系の実装を指す。Win32c9x系の実装。'c'は「compatibility」の頭文字である。しかし、現在では9xの実装も区別なくWin32と呼ぶ。Win32sWindows 3.1用の実装。's'は「subset」の頭文字である。Windows 3.1には搭載されておらず、別途入手・インストールする必要がある。Win32 for Windows CEWindows CEの実装。文字コードにUnicodeのみを使用するなどの点が特徴的である。WOW64 Win64上でWin32をエミュレーションするサブシステムによる実装。Windows NTがx86以外のアーキテクチャに移植されたことに伴い、Win32は各種アーキテクチャ向けに移植されている。また、Windows NTではないが、かつてMacintosh用のWin32も存在し、Microsoft Visual C++ 4.0 Cross-Development Edition for Macintoshとしてクロスコンパイラとともに発売されていた。これらアーキテクチャの異なるWin32の間にはソースコード上での互換性がある。

3.3. Win64
----------

Win64は、64ビットプログラム用の実装である。2021年3月現在の主流はx64だが、Windows 10ではARM64もサポートされるようになった。

かつてWindows Server 2003およびWindows XPにてIA-64のサポートが始まったが、Windows Server 2008 R2を最後にサポートが打ち切られた。

3.4. マイクロソフト以外による実装
-------------------

Windows APIの仕様はWindows SDKのドキュメントやMicrosoft Docsで公開されており、それを基にしたMicrosoft Windows以外のWindows APIの実装が存在する。

Wine
ReactOS
HX DOS Extender

4. WindowsランタイムAPI
------------------

WindowsランタイムAPI  は、Windows 8で導入されたWindowsストアアプリ  を開発するためのCOM拡張による高レベルAPI。後継となるWindows 10で導入されたユニバーサルWindowsプラットフォーム  アプリケーションの開発におけるベースAPIにもなっている。一部のWinRT APIは、従来のデスクトップアプリケーションから利用することもできる。従来のWindows APIは、WinRT APIと対比・区別されるとき、Win32 APIと呼ばれることが多い。

5. 詳細
-----

5.1. Unicode対応
--------------

Windows NT系では当初からUnicodeが用いられている一方、Unicodeに対応していないWin16と互換性を取るために、Win32 APIから同じAPIに対してマルチバイト文字版とUnicode版の2つを用意し、C/C++のマクロを駆使してコンパイル時にどちらを使うか選択できる仕組みが採用されている。なお、Unicodeの符号化には当初UCS-2が、Windows 2000から正式にUTF-16が用いられている。

具体的には、文字および文字列の関わる関数・構造体について、マルチバイト文字とUnicode  のどちらを与えることもできるように、2つの関数・構造体などが準備されている。その場合、マルチバイト文字列を与えるべき関数・構造体は末尾に「A」を付け、ワイド文字列を与えるべき関数・構造体は末尾に「W」を付けて区別している。例えば、Win16のMessageBox関数に対して、Win32ではMessageBoxAとMessageBoxWという2つの関数が用意されている。そして、プリプロセッサ識別子UNICODEの定義の有無によって切り替えが行われる。

ifdef UNICODE
define MessageBox MessageBoxW
else
define MessageBox MessageBoxA
endif<WtXmlEndTag /> さらに、文字型に対しても同様にCHAR  とWCHAR  をUNICODEの定義に応じて切り替えるTCHAR型などや、ナロー文字列定数・リテラルとワイド文字列定数・リテラルを切り替えるTEXTマクロが存在する。

ifdef UNICODE
define TEXT L ## stypedef WCHAR TCHAR;

else
define TEXT stypedef CHAR TCHAR;

endif<WtXmlEndTag /> これらを適切に用いると、1つのソースコードからコンパイル時のオプションによってマルチバイト文字を用いる実行プログラムとワイド文字を用いる実行プログラムの2種類が作成できる。以下はその例である。

include
include // WinMain と wWinMain を切り替える _tWinMain などが定義されている。int WINAPI _tWinMain { MessageBox, TEXT, MB_OK); return 0; }<WtXmlEndTag />

なお、Windows NT系におけるA版のAPI関数は、内部的にW版を呼び出すラッパーとなっている。A版APIに入力されたマルチバイト文字列はUnicode文字列に変換されてからW版APIに入力され、W版APIから出力されたUnicode文字列はマルチバイト文字列に変換されてA版APIの出力となる。

このプレフィックスのAはANSI、WはWideを意味する。ANSIは、Windowsコードページの一部がANSI規格のドラフトを元にしたことに由来する。ワイド文字  は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へ傾斜する傾向にある。

6. 歴史
-----

Windows APIの歴史は、もちろんWindows自体の歴史と切り離せない関係にある。常に、Windowsに新機能が搭載されれば、それをアプリケーションソフトウェアから使用するための新しいAPIが追加され、対応する新しいSDKが公開されることの繰り返しである。デバイスドライバーに対応を迫るものは、DDK/WDK経由で公開される。

Windows APIの歴史上、最も大きな変革はWindows NTに伴うWin32の登場だった。ポインタとハンドルも32ビット化されたこと、Unicodeへの対応が図られたことが大きな変化である。

なお、現在は緩やかに64ビットへの移行が進んでいる。Win64では、ポインタおよびハンドルは64ビット化されているが、それ以外では16ビットから32ビットへの移行時のような大きな変化はない。なお、64ビット版Windowsでは32ビットアプリケーションとの相互運用性を確保するため、ハンドルの上位32ビットを使用する仕組みとなっており、ウィンドウ  などのユーザーオブジェクトハンドル、ブラシ  やペン  などのGDIオブジェクトハンドル、そしてミューテックス、セマフォ、ファイルなどの名前付きオブジェクトハンドルを32ビット/64ビットアプリケーション間で共有し、プロセス間通信に利用することができる。また、64ビット版WindowsではWOW64により32ビットアプリケーションを実行できるが、16ビットアプリケーションを実行することはできない。

7. 互換性
------

Windows APIはシステム全体で共有するDLLを通じて公開されており、このシステムDLLに変更が入るとすべてのアプリケーションが影響を受けることになる。このため、度重なるバージョンアップやセキュリティパッチの適用によりコンポーネントの互換性を失ってしまうことによるDLL地獄  の発生を招くことがある。この点に関しては、Windows 2000で導入されたSide-by-Sideコンポーネント共有や、Windows XPで導入された分離アプリケーションとSide-by-Sideアセンブリの仕組みにより、ある程度の解決が図られている。

基本的にWindowsおよびWindows API自体は互換性に配慮した設計がなされており、バージョンアップの際に既存の公開APIに破壊的変更が入ることはない。公開APIを正しく利用して開発されたアプリケーションやドライバーであれば、旧バージョンのOSで正常に動作していたものは、ほとんどのケースにおいて修正することなく動作する。セキュリティ対策のためにWindows Vistaで導入されたユーザーアカウント制御  に関しても、通常権限のアプリケーションが直接アクセスできないディレクトリに対する読み書きを仮想化してリダイレクトする仕組みが救済策として用意されている。しかし、アプリケーションやドライバーが特定のバージョンのWindowsでしか動かないような設計になっていた場合、アプリケーションが起動できない、正常に動作しないなどの互換性問題が発生することがある。この問題の回避策のひとつとして、Windowsには、旧バージョンのOSの動作をある程度エミュレートする「互換モード」が用意されている。例えばバージョン番号を取得するためのWindows APIにおいて旧バージョンのOSを偽装した値を返すようにすることで、これらに依存したアプリケーションへの影響を低減する。

8. 批判
-----

Windows APIはWin16を拡張して32ビット、64ビット化されたという歴史がある。そのため度重なる機能の追加により、高度に複雑化しその習得が困難と化しているという問題がある。

Windows 8で導入された新規設計のWinRT APIは、名前空間を利用して体系的に整理されており、効率的かつモダンなアプリケーション開発をサポートするが、Windowsストアアプリはサンドボックス環境で動作するために制約が多く、サードパーティー開発の主流とはならなかった。結局は従来のWin32 APIや.NET Frameworkを使用したデスクトップアプリケーションが主流のままであるが、Win32 APIによる開発はGUIツールキットのサポートが弱く、レガシーな外観のGUIウィジェットしか使えないなどの問題がある。

9. ラッパーライブラリ
------------

Windows APIは比較的低水準であるため、高水準なインターフェイスを持たせたり、C/C++以外の言語から利用したりするための様々なラッパーライブラリやフレームワークが数多く存在する。主なものは次のとおり。

9.1. マイクロソフト
------------

Microsoft Foundation Class C++クラスによるWindows APIのラッパー。Active Template Library C++テンプレートによるCOMのラッパー。Windows Template Library ATLの拡張として作られた軽量のWindows APIのラッパー。現在はCPLに基づくオープンソースとなっている。

9.2. ボーランド
----------

Object Windows Library MFCと同時期に公開され、よりオブジェクト指向に作られたラッパー。Visual Component Library ボーランドがその後に開発したDelphiによるラッパー。Windows Formsのベースにもなった。.NET FrameworkやWindows版.NET Coreは、内部的にWindows APIを利用して実装されているものの、基本クラスライブラリなどはプラットフォーム非依存となるよう抽象化されているが、Windows固有の機能を使用したGUIフレームワークや、Windows APIを薄くラップしただけの部分も存在し、System.Windows名前空間やMicrosoft.Win32名前空間などにまとめられている。

10. 脚注
------

11. 関連項目
--------

Component Object Model 
Object Linking and Embedding 
Microsoft DirectX
.NET Framework
Microsoft Windows SDK
Windowsランタイム 
Windows UI Library 

12. 参考文献
--------

Charles Petzold著　『プログラミングWindows第5版〈上〉』　アスキー、2000年。ISBN 4756136001
Charles Petzold著　『プログラミングWindows第5版〈下〉』　アスキー、2000年。ISBN 475613601X
Jeffrey Richter著　『Advanced Windows 改訂第4版』　アスキー、2001年。ISBN 4756138055

13. 外部リンク
---------

[1]
[2] - Windows 7までのAPIドキュメント