レガシー Windows API(概要)について

ここで紹介しているAPIは、Windows95、Windows NT3.5時代のAPI群であり、最新のAPIは含まれていないことに注しして欲しい。なお、当時の解説書は現在よりもより詳細に解説しているため、参考になるはずである。

  • レイアウトを変換する際、崩れているページがあります。
  • 概要およびSampleコードはありますが、APIの解説はありません。

ご要望があれば旧版のWin32 API(HELP形式)をお譲りします。問い合わせフォームより申し込みください。

Windows API Win32(R) ベースのアプリケーションでのプロセス間通信

ユーザーは、 コンピュータに慣れてくるにつれて、 より強力なアプリケーションを必要とするようになります。この要求を満たすにはアプリケーションにより多くの機能を付加しなければならず、 その結果アプリケーションは巨大化します。開発の点から見ても、 ユーザー インターフェイスの点から見ても、 巨大化したアプリケーションはその管理が困難になります。このため、 特定の機能を専門にこなすアプリケーションを複数作成し、 専門化した各アプリケーションがほかのアプリケーションと通信したりデータを共有することによって処理を行うという方法が注目を浴びるようになってきました。もはや1つのアプリケーションでユーザーの要望をすべて実現する必要はなくなりました。互いに協調し合い、 通信し合うアプリケーションの時代が来たのです。
Microsoft(R) Win32(R) アプリケーション プログラミング インターフェイス (API) では、 アプリケーション間の通信やデータ共有のためのさまざまな機構を用意しています。これらの機構によって実現される処理は、 「プロセス間通信 (IPC)」と呼ばれます。IPCでは、 ある作業をいくつかの専門化されたプロセスに分担させることができるほか、 ネットワーク上の互いに協調し合うコンピュータ間で計算負荷を分散させることもできます。
通常、 互いに協調し通信し合うアプリケーション群は、 クライアントとサーバーに分類されます。クライアントとは、 ほかのプロセスにサービスを要求するアプリケーションやプロセスのことです。サーバーとは、 クライアントの要求に応答するアプリケーションやプロセスのことを指します。また、 状況に応じてクライアントおよびサーバーの両方として動作するアプリケーションも多くあります。たとえば、 ワード プロセッサ アプリケーションが表計算アプリケーションに対して製造コストの要約表のデータを要求するとき、 ワードプロセッサ アプリケーションはクライアントとして動作し、 表計算アプリケーションはサーバーとして動作します。一方、 その表計算アプリケーションが自動在庫制御アプリケーションに対して最新の在庫データを要求するときは、 表計算アプリケーションはクライアントとして動作します。

 

開発について

アプリケーションでIPCを利用する場合は、 どのIPCを利用するかを決定する前に、 次に示すいくつかの問題を考慮してください。

  • アプリケーションが、 ネットワーク上のほかのコンピュータで動作しているアプリケーションと通信できるようにするかどうか。また、 そうしない場合にローカル コンピュータ上で動作しているアプリケーションと通信するだけで十分かどうか。つまり、 アプリケーションを「ネットワーク対応」にするかどうか。IPCには、 ローカル コンピュータとネットワークの両方で使えるものと、 ローカル コンピュータでしか使えないものがあります。
  • 異なるオペレーティング システム (MS-DOS(R) Microsoft(R) Windows(TM) バージョン3.x、 UNIX(R) など) で動作しているほかのコンピュータのアプリケーションと通信できるようにするかどうか。つまり、 アプリケーションを「相互操作可能」にするかどうか。
  • アプリケーションの通信相手のアプリケーションをユーザーが選択できるようにするか、 それとも暗黙に通信相手を見つけるか。
  • 切り取りや貼り付けなどの一般的な操作方法でほかの多くのアプリケーションと通信するか、 それとも通信条件を限定して、 特定のアプリケーションとだけ通信するか。一般的な方法による通信は、 「疎結合」と呼ばれます。より厳密に定義された方法による通信は、 「密結合」と呼ばれます。
  • 性能がアプリケーションの最重要の部分であるかどうか。どのようなIPC機構にも何らかの通信オーバーヘッドがあります。
  • アプリケーションをWindows用アプリケーションにするか、 それとも文字モードの機能を持つアプリケーションで十分か。このトピックで説明するIPC機構には、 文字モード専用のアプリケーションでは使えないものもあります。クリップボードや動的データ交換 (DDE)、 オブジェクトのリンクと埋め込み (OLE) を使うアプリケーションは、 少なくとも1つのウィンドウを持っていなければなりません。

以上の問題をどうするかによって、 Win32 APIで利用可能なIPC機構をアプリケーションが有効に使えるかどうかが決まります。このトピックでは、 Win32の各IPC機構の長所と短所について説明します。

 

ファイル マッピング

プロセスは、 「ファイル マッピング」を使って、 ファイルの内容をプロセスのアドレス空間内のメモリ ブロックとして扱うことができます。このため、 プロセスは、 ファイルI/O操作を使わずに、 簡単なポインタ操作でファイルの内容を調べたり修正したりすることができます。
Win32 APIでは、 複数のプロセスが同じ「ファイル マッピング オブジェクト」にアクセスできます。各プロセスは、 自分自身のアドレス空間内のメモリを指すポインタを持ちます。プロセスはこのポインタを使って、 ファイルの内容の読み取りや修正を行うことができます。
ファイル マッピング オブジェクトをプロセス間で共有するには、 次の3つの方法があります。

  • 継承。1番目の (親) プロセスがファイル マッピング オブジェクトを作成し、 そのオブジェクトのハンドルを子プロセスが継承できるようにします。
  • 名前付きファイル マッピング。1番目のプロセスが既知の名前 (ファイル名と異なっていてもかまいません) でファイル マッピング オブジェクトを作成します。2番目のプロセスは、 その名前を指定してファイル マッピング オブジェクトを作成します。また、 1番目のプロセスが一意な名前でファイル マッピング オブジェクトを作成し、 ほかのIPC機構 (名前付きパイプやメールスロットなど) を使って、 その名前を2番目のプロセスに渡すこともできます。
  • ハンドルの複製。1番目のプロセスがファイル マッピング オブジェクトを作成し、 そのオブジェクトのハンドルを次のプロセスに渡します。2番目のプロセスは、 ハンドルを複製して、 共有メモリにアクセスできます。1番目のプロセスは、 ほかのIPC機構 (名前付きパイプやメールスロットなど) を使って、 ファイル マッピング ハンドルを2番目のプロセスに渡すことができます。ハンドルの複製について詳しくは、 同期の概要を参照してください。

複数のプロセスが共有メモリ ブロックに読み書きアクセスを行う場合は、 セマフォなどの何らかの同期オブジェクトを使って、 マルチタスク環境でのデータの破壊を防いでください。

ファイル マッピングはかなり効率的であり、 オペレーティング システムがサポートしているセキュリティ属性によって不用意なデータ破壊を防ぐこともできます。ファイル マッピングは、 ローカル コンピュータ上のプロセス間でしか使えず、 ネットワークでは使えません。しかし、 アプリケーションは、 リモート マウントされたボリュームのファイルのファイル マッピング オブジェクトを作成できます。たとえば、 リモート サーバーが F: ドライブとしてマウントされている場合、 アプリケーションは、 そのボリューム上のファイルのファイル マッピング オブジェクトを作成できます。しかし。リモート サーバーで動作しているプロセスは、 ローカル コンピュータ上で動作しているプロセスとファイル マッピング オブジェクトを共有することはできません。

メモ

ファイル マッピングは、 同じコンピュータ上で複数のプロセスがデータを共有する場合には効率的ですが、 プロセス間での同期を考慮しなければなりません。詳しくは、 ファイル マッピングの概要と同期の概要を参照してください。

 

共有メモリ

Win32 APIは、 特殊なファイル マッピングによって、 プロセス間での共有メモリ アクセスを実現しています。ファイル マッピング オブジェクトを作成するときにシステム スワップ ファイルを指定すると、 そのファイル マッピング オブジェクトは共有メモリ ブロックとして扱われます。ファイル マッピングの概要で説明しているように、 ほかのプロセスは、 同じファイル マッピング オブジェクトをオープンすることによって、 同じメモリ ブロックをアクセスできます。
共有メモリはファイル マッピングで実現されているため、 セキュリティ アクセス属性をサポートしていますが、 同じコンピュータで動作しているプロセス間でしか使えません。

メモ

Win32 APIの共有メモリはファイル マッピングで実現されています。ファイル マッピングの特徴は共有メモリにも当てはまります。詳しくは、 ファイル マッピングの概要を参照してください。

 

名前なし (匿名) パイプ

名前なし (匿名) パイプは、 関連するプロセスどうしがファイルの読み書きと同じような方法で情報を相互に転送できるものです。通常、 名前なしパイプは、 子プロセスがその標準I/Oをリダイレクトして親プロセスとデータを交換するのに使われます。
名前なしパイプを使うには、 一般に親プロセスがパイプを作成し、 そのハンドルを子プロセスに継承させて読み書きできるようにします。親プロセスがパイプにデータを書き込むと、 子プロセスはパイプの端点からデータを読み取ることができます。同様に、 子プロセスがパイプにデータを書き込むと、 親プロセスはパイプの端点からデータを読み取ることができます。また、 親プロセスは、 1つの名前なしパイプの読み書きハンドルを継承する子プロセスを複数作成できます。これらの子プロセスは、 パイプを使って、 親プロセスを介さずに直接相互に通信できます。
名前なしパイプはネットワークでは使えず、 関連しないプロセス間でも使えません。関連しないプロセス間やネットワークで使えるパイプ機構については、 名前付きパイプを参照してください。

メモ

名前なしパイプによって、 同じコンピュータ上の子プロセスのI/Oを効率的にリダイレクトできます。詳しくは、 パイプの概要を参照してください。

 

名前付きパイプ

名前付きパイプは、 名前なしパイプと同様に、 プロセス間でのデータ転送に使われます。しかし、 名前なしパイプとは異なり、 名前付きパイプは、 関連しないプロセス間やコンピュータ間のネットワークでも使えます。通常、 サーバー プロセスは既知の名前で名前付きパイプを作成します。パイプの名前を知っているクライアント プロセスは、 パイプの端点をオープンできます。このとき、 パイプの作成側によって指定されるアクセス制限が適用されます。サーバーとクライアントが接続すると、 双方からパイプに対して読み書き操作を実行してデータを交換できるようになります。また、 パイプの作成側がパイプを作成し、 そのパイプのハンドルを子プロセスに継承させたり、 一意な名前でパイプを作成し、 (クライアントが管理するメールスロットなどの) ほかのIPC機構を使ってその名前をクライアントに渡すこともできます。

メモ

名前付きパイプでは、 ネットワーク上でデータを転送する場合でも、 同じコンピュータ上のプロセス間でデータを転送する場合と同じくらい簡単なプログラミング インターフェイスを使うことができます。詳しくは、 パイプの概要を参照してください。

 

メールスロット

メールスロットは、 単方向のプロセス間通信機能を実現します。どのようなプロセスでも、 メールスロットを作成してメールスロット サーバーになることができます。メールスロット クライアントと呼ばれるほかのプロセスは、 メールスロットの名前を使ってメールスロットにアクセスし、 メール サーバー プロセスにメッセージを送ることができます。プロセスはメールスロット サーバーとメールスロット クライアントの両方になることができるため、 複数のメールスロットを使えば双方向IPCの実現も可能です。
送られてくるメッセージは、 常にメールスロットに付加されます。メールスロットには、 それを作成したプロセスがメッセージを読み取るまでメッセージが保存されます。
メールスロットは名前付きパイプに似ていますが、 プログラミング インターフェイスはより簡単で、 特定のネットワーク ドメイン内のすべてのコンピュータにメッセージをブロードキャストする機能もあります。メールスロット クライアントは、 ローカル コンピュータ上のメールスロット、 ほかのコンピュータ上のメールスロット、 および、 特定のネットワーク ドメイン内のすべてのコンピュータ上にある同じ名前のすべてのメールスロットに、 それぞれメッセージを送ることができます。ドメインにブロードキャストするメッセージは400バイト以下でなければなりません。単一のメールスロットに送るメッセージのサイズは、 メールスロットを作成したプロセスが指定する最大メッセージ サイズだけに制限されます (無制限にすることもできます)。

メモ

メールスロットを使えば、 アプリケーションは短いメッセージを簡単に送受信することができます。また、 ネットワーク ドメイン内のすべてのコンピュータにメッセージをブロードキャストすることもできます。詳しくは、 メールスロットの概要を参照してください。

 

クリップボード

クリップボードは、 Windows用アプリケーション間で簡単なデータ共有を行うためによく使われる、 切り取りおよび貼り付けの機能を実現する機構です。アプリケーションはクリップボードを使って、 さまざまな標準形式データやアプリケーション定義の形式を持つデータを読み書きできます。
クリップボードは、 アプリケーション間でデータを共有するときの主要な保管場所として動作します。ユーザーが切り取りまたは貼り付けの操作を実行すると、 アプリケーションは、 選択されているデータを1つ以上の形式でクリップボードに置きます。ほかのアプリケーションは、 自分が利用できる形式を使ってクリップボードからそのデータを取得できます。クリップボードは非常に「疎」な結合しか持たないデータ交換手段であり、 アプリケーションどうしがあらかじめ同意しておかなければならないのは、 データ形式だけです。
クリップボード機構は、 同じコンピュータ上のアプリケーション間や、 ネットワークの別のコンピュータ上で動作するアプリケーション間で使えます。また、 クリップボードはWindows用アプリケーション間でしか使えませんが、 Microsoft(R) Windows NT(TM) オペレーティング システムで動作する16ビットWindows 3.xアプリケーションは、 Windows NT用に作成された32ビット アプリケーションとクリップボード データを交換することができます。

メモ

Windows用アプリケーションは、 自分が処理できるデータ形式を必ずサポートしなければなりません。たとえば、 テキスト エディタやワード プロセッサは、 少なくとも純粋なテキスト形式でのクリップボード データのやり取りをサポートしなければなりません。詳しくは、 クリップボードの概要を参照してください。

 

動的データ交換

動的データ交換 (DDE) は、 アプリケーション間でさまざまな形式のデータを交換するためのプロセス間通信プロトコルです。アプリケーションは、 DDEを使ってデータを1回だけ交換したり、 新しいデータが利用可能になるたびに互いにデータを何度も交換し合ってデータを更新したりすることができます。

DDEで使われるデータ形式は、 WindowsのクリップボードによるIPC機構で使われるデータ形式と同じです。DDEは、 クリップボードの機構を拡張したものと考えることができます。通常、 メニューから[貼り付け]コマンドを選ぶときなど、 ユーザーのコマンドに対して1回限りで応答する場合には、 クリップボードが使われます。DDEもユーザーのコマンドによって開始されますが、 ユーザーとの対話を行わないまま動作し続けます。
DDEによるデータ交換には、 次の3種類があります。

  • コールド リンク: クリップボードのように、 交換は1回限りのデータ転送で行われます。
  • ウォーム リンク: サーバーは、 データが変更されるとクライアントに通知し、 クライアントは新しいデータを要求します。
  • ホット リンク: サーバーは、 データが変更されると、 最新のデータをクライアントに送ります。


DDEは、 同じコンピュータ上のアプリケーション間や、 ネットワークの別のコンピュータ上で動作するアプリケーション間で使うことができます。

メモ

市販されているほとんどのWindows用アプリケーションは、 DDEをサポートしています。DDEをサポートすることによって、 同じくDDEをサポートするほかのWindowsアプリケーションとの間で、 クリップボードと同じように、 さまざまな標準形式によるデータ交換を行うことができます。また、 より密な結合を必要とするアプリケーション間では、 特別なIPCを実現するために独自のDDEデータ形式を定義することもできます。詳しくは、 動的データ交換の概要と動的データ交換管理ライブラリの概要を参照してください。

 

オブジェクトのリンクと埋め込み

「オブジェクトのリンクと埋め込み (OLE)」アプリケーションは、 「複合ドキュメント」(さまざまな種類のアプリケーションのデータを持っているドキュメント) を管理します。OLEは、 ほかのアプリケーションを呼び出して簡単にデータを編集するというサービスを提供します。たとえば、 OLE対応のワード プロセッサは、 表計算アプリケーションのグラフを埋め込むことができます。ユーザーが埋め込まれたグラフを編集用として選ぶと、 表計算アプリケーションが自動的に起動します。表計算アプリケーションの起動や編集用のグラフのレンダリングは、 OLEライブラリが行います。ユーザーが表計算アプリケーションを終了すると、 元のワード プロセッサのドキュメント内でグラフが更新されます。これに対して、 DDEリンクを使ってワード プロセッサのドキュメント内に表計算グラフを含めている場合には、 グラフを変更するために、 ユーザーは表計算アプリケーションを明示的に起動してグラフ ドキュメントをオープンしなければなりません。OLEでは、 表計算アプリケーションはワード プロセッサの拡張機能のように見えます。
DDEを使うアプリケーションと同様に、 OLE対応アプリケーションはさまざまなWindows用アプリケーションと通信できます。OLEプロトコルには必要なコンテキスト情報がすべて含まれているため、 アプリケーションは、 ほかのすべてのOLEアプリケーション (まだ作成されていないものでも) とのOLE対話を保持できます。

メモ

OLEは、 複合ドキュメントをサポートし、 アプリケーションで埋め込みデータやリンク データを利用できるようにします。ユーザーはこれらのデータを選ぶと、 自動的に別のアプリケーションをデータ編集用として起動することができます。これにより、 アプリケーションは、 ほかのOLE対応アプリケーションを自分の拡張機能として利用することができます。

 

ダイナミック リンク ライブラリ

Win32ダイナミック リンク ライブラリ (DLL) を構築すれば、 そのDLLを呼び出すプロセス間でDLLのグローバル データを共有することができます。互いに協調して動作するプロセスは、 DLLを呼び出して、 DLLが所有するグローバル データを調べたり修正したりできます。たとえば、 DLLのグローバル データ空間にデータを格納するDLL関数をプロセスAが呼び出し、 そのデータを取得する別のDLL関数をプロセスBが呼び出すことができます。もちろん、 Win32 APIにはマルチタスク機能があるため、 DLLはセマフォなどの同期オブジェクトを使って、 共有メモリへのアクセスを制御しなければなりません。
DLLでは共有のグローバル データを使うこともできますが、 共有メモリを使う場合にはWin32のファイル マッピングを使ってください。ファイル マッピングはより効率的であり、 アクセス保護の機能もあります (たとえば、 クライアントによるファイル マッピング オブジェクトへのアクセスを、 読み取り専用に制限することができます)。

メモ

DLLでは共有のグローバル データ セグメントを使ってアプリケーション間でデータを共有することもできますが、 共有メモリを使う場合はWindows NTのファイル マッピング関数を使って作成してください。詳しくは、 ダイナミック リンク ライブラリの概要を参照してください。

 

リモート プロシージャ コール

Win32 APIでは、 関数を遠隔的に呼び出すための「リモート プロシージャ コール」(RPC) が提供されています。RPCを使えば、 ほかのプロセスとの通信を関数の呼び出しと同様に簡単に行うことができます。RPCは、 単一のコンピュータ上のプロセス間や、 ネットワーク上の異なるコンピュータ上のプロセス間で使えます。RPCは、 ネットワーク上で動作するDLLともいえます。
Win32 APIのRPCは、 Open Software Foundation (OSF) の分散処理環境 (Distributed Computing Environment, DCE) に準拠しています。つまり、 Win32 APIを使って作成されたRPCアプリケーションは、 DCEをサポートしているほかのオペレーティング システムで動作しているRPCアプリケーションと、 通信することができます。RPCは、 さまざまなハードウェア アーキテクチャやバイト順序の違いなどを考慮して、 自動的にデータ変換をサポートします。
Win32の開発キットには、 MS-DOSをホストとするRPCクライアントをサポートする、 RPCライブラリが付属しています。Windows NTサーバーは、 この機能を使ってRPCによるサービスをMS-DOSクライアントに提供できます。
RPCのクライアントとサーバーは密結合されていますが、 依然として高い性能を維持しています。Windows NTではRPCの仕様が拡張され、 オペレーティング システムのさまざまな部分でクライアントとサーバーとの関係を密にするために使われています。

メモ

RPCは関数インターフェイスによるIPCを実現し、 自動的なデータ変換やほかのオペレーティング システムとの通信をサポートします。RPCを利用することにより、 高性能で密結合の分散型アプリケーションを開発できます。詳しくは、 「Microsoft Win32 Remote Procedure Call Programmer's Guide and Reference」を参照してください。

 

Netbios関数

Win32 APIは、 低レベルのネットワーク制御ファンクションを処理するNetbios関数をサポートしています。この機能は、 主にIBMのNetBIOSシステムを使って作成したアプリケーションをWindowsに移植しなければならない場合のために用意されています。新しくアプリケーションを作成するときは、 低レベルのNetbiosファンクションではなく、 このトピックですでに説明したほかのIPC機構を使うようにしてください。Win32 APIで提供されているIPCの機構は、 低レベルのNetBIOSの機能の多くの部分をカプセル化して見えなくしており、 アプリケーションを開発するときにそれらを実装する必要がなくなっています。

たとえば、 Win32のメールスロットをエミュレートするには、 次に示すNetBIOS動作が必要になります。

サーバー側

  • ローカル テーブルへの名前の追加
  • セッション接続のリッスン
  • 接続によるデータの読み取り
  • メッセージ キューへのデータの付加
  • セッションのクローズ
  • 別のセッション接続のリッスン
  • キューに置かれているメッセージの取得の許可


クライアント側

  • セッションのオープン
  • データの書き込み
  • セッションのクローズ

メモ

Netbios関数は、 IBM NetBIOSシステムを使って作成されている既存のアプリケーションを移植したり、 低レベルのネットワーク機能にアクセスしなければならない特殊なアプリケーションを作成するためだけに用意されています。通常のアプリケーションでは、 Win32 APIで利用可能な高レベルのIPC機構を使ってください。詳しくは、 ネットワークの概要を参照してください。

 

まとめ

アプリケーションは、 このトピックで説明した機構のいくつかを使ってIPCをサポートすることになります。たとえば、 すべてのWindows用アプリケーションは、 少なくともクリップボードだけはサポートすべきです。また、 アプリケーションは、 DDEやOLEを使って、 DDEプロトコルやOLEプロトコルをサポートするさまざまなアプリケーションと疎結合の通信を行うことができます。これらの疎結合の通信機構の長所は、 相手のアプリケーションを知らなくてもそのアプリケーションとデータを共有できるという点です。クリップボード、 DDE、 OLEなどのプロトコルをサポートすることによって、 新しいアプリケーションともデータを共有できます。これらのプロトコルをサポートする新しいアプリケーションが開発されても、 そのままそのアプリケーションと通信することができます。
アプリケーションをより高度に作成するには、 アプリケーションの処理を、 共有メモリ、 パイプ、 RPCなどによって通信を行う個々の密結合の操作に分割するのも1つの方法です。このような密結合の機構によって、 高性能な拡張機能をアプリケーションにもたらすことができます。ただし、 このような高度なIPC機構を追加する場合は、 ほかの多くのWindows用アプリケーションともデータを共有できるように、 疎結合のIPC機構をサポートすることも忘れないようにしてください。

▲ページトップに戻る

【本を読んでもよくらからない】 … 個別指導でわかりやすくお教えします