Windows APIはもう古い!
今後のWindowsのすべてはOLEにはじまりOLEに終わる
OLEオートメーションのメカニズムとオブジェクト指向な未来
OLE 2.0でサポートされ、初めてVisual Basic 3.0で実装されたOLEオートメーションは、アプリケーションをコンポーネント化、カプセル化して再利用することが可能なメカニズムである。そして、アプリケーションだけではなくOLEの標準的なインターフェイスで使用できるカスタムコントロール(OCX)も登場している。これらのテクノロジーはWindows 95やWindows NTでの開発環境やスタイルを、コンポーネント指向に大きく変えようとしている。すでにVisual BasicからWindows APIを使うようなプログラミングは古い。これからはすべてがOLEになるのだ。
ここでは、OLEのもっとも重要なメカニズムである
OLEオートメーションのメカニズムとその将来性について述べる。
酒井 法雄
●OLEはプロセス間通信である
OLE(Object Linking and Embedding)と言えば、とかくWordの文書にExcelのシートやチャートを貼り付けるといったことを連想しがちである。ここからくるOLEのイメージは、複数のアプリケーションでのデータ共有というものである。本来OLEは、Microsoft Power Pointで文字や図形を自由に貼り付けてデザインできるようにするために開発されたものであるから、この連想はあながち外れてはいない。しかし、数年前に発表されたOLE 2.0からは、すでにOLEはその方向性を大きく変えているのである。そして、今のVisual BasicやWindows 95では、好むと好まざるとにかかわらず、知らないうちにOLEを使っているのである。すでに、OLEがないWindowsは考えられない状態になっているのである。
端的に言うならば、OLEはプロセス間通信ある。こう捉えると、その存在価値もかなり違って見えるはずだ。Windowsでのプロセス間通信の歴史(厳密には、Windows
3.1まではプロセスとは言わなかったので、アプリケーション間通信と言うべきだろう)を振り返ると、クリップボードからスタートし、メッセージベースDDE(Dynamic Data Exchange)、APIベースのDDE、そしてOLEという流れがある。そしてドラッグ&ドロップインターフェイスを統合した形で出てきたのが、OLE 2.0(図)である。今ではOLEといえば2.0のことを指すのが一般的である。
この短い歴史の中で注目したいのがDDEである。DDEは手動、自動、通知という3つのリンク形態を持ち、ソース(サーバー)側のデータをディスティネーション(クライアント)側にコピーして共有しようというものである。また、一時的にディスティネーション側データをソース側に転送することも可能である。さらに、ディスティネーション側からソース側にコマンド文字列を送信することもできる。この機能を使えば、二つのアプリケーション間でのデータ共有のみならず、通信も比較的自由にプログラミングすることができたのである。
しかし、当初のDDEはメッセージベースだったため、プロトコルに合わせて矛盾なくコーディングするのが難しかった。その後DDEML.DLLが提供されてAPIベースとなったものの、非同期で動作するDDEは、相手からの反応を待つループを作成する必要があった。さらに、ノンプリエンプティブな16bit Windowsではドラッグやディスクアクセス、重い処理などが間に入ったときにリンクを保持し続けることができずに、うまく動作しないといった問題点が指摘された。
OLEは、DDEの手続きを簡略化し、もっと手軽にアプリケーションから使えるようにすることを目標とされた。このため、あくまでも複合ドキュメントを主眼とし、データのファイルをサーバー側が管理するリンクと、クライアント側が管理するエンベッドの二つの方法が提供された。しかし、扱えるデータ型は相変わらずクリップボード形式のものであり、グローバルメモリのアドレスを使ってデータのやり取りをしており、64Kbytesの壁を越えられないというDDEそのままの制限があった。それもそのはず、実はOLEのデータのやり取りをする中心となるOLECLI.DLLとOLESVR.DLLの間はあくまでも非同期のDDEが使われていたのである。また、本来のプロセス間通信の機能は仕様上は残されたものの、現実的には対応するアプリケーションはほとんどなかった。また、以前のVisual BasicからはOLEサーバーを作成できなかったため、現実的にはOLEとはOLE対応アプリケーションとのデータ共有以外に使い道はなかったのである。
●OLE 2.0の特徴と構造
OLE 2.0では、このようなOLE 1.0の仕様を解決すべく、大幅な見直しが行われた。その主眼となる目標も、WordにExcelを貼り付けるような複合ドキュメントの強化だけにとどまらず、ユーザーインターフェイスと操作性の改良、さらにはWindowsアプリケーション間での共通マクロとも言えるOLEオートメーションが掲げられた。結果的には、次のような改良が行われた。
OLE 2.0はこれらの機能を実現するために、従来とはまったく違う構造を取っている。
図 OLE 2.0のアーキテクチャー
OLE 2.0の中心となるのが、コンポーネントオブジェクトモデル(COM)である。ここでは、オブジェクトのインスタンスを作成し、オブジェクトのメンバー関数APIのアドレスを供給する。
32bit Windowsでは、プロセス単位でメモリが管理される。16bitアプリケーションもまとめて一つのプロセスとして扱われる(NTでは個別のプロセス空間に配置することも可能)。プロセスはOSの安定動作に貢献している。というのも、一つのプロセスが異常終了しても、他のプロセスは影響を受けないような頑強なメモリ管理がされている。つまり、システム全体としての安定度を向上させているわけだ。このような頑強なプロセスを乗り越えて通信するには、それなりに難しい側面がある。さらに、32bitと16bitのプロセス空間では、使われる文字コードもUniCodeとANSIという違いがあるし、メモリの使い方も違う。このようにプロセス間通信を行うときの各種の整合性を取るのが、マーシャリングと呼ばれる処理だ。
マーシャリングのベースとなるのが、LRPC(Lightweight Remote Procedure Calls)と呼ばれるプロセス間通信である。従来の非同期なDDE方式に比較すると、同期して実行されるのでインプリメントがしやすいというメリットがある。また、いわゆるRPCと同様にプロシージャを呼び出すという考え方であるから、二つのパラメータしか持てないSendMessage関数を使うのと比較して、引数に自由度がある。
実際には、LRPCはインターフェイスと呼ばれる関数群をコールして実行される。サーバーオブジェクトには、あらかじめ自オブジェクト内のデータを操作するためのメソッド(メンバー関数)を用意しておく。COMではこれらのメソッドの一覧をvtableと呼ばれるテーブルに作成して、そのアドレスを管理する。クライアント側ではCOMを通してアクセス可能なメソッド一覧およびそのアドレスを知ることができる。そして、必要に応じてそのメソッドをプロシージャコールするわけだ。
●OLE オートメーションとは
このようなOLEのメカニズムのメリットを最大に活かしたのが、OLEオートメーションである。OLEオートメーションは、インターフェイス関数群をそのままサーバー側オブジェクトから公開された関数(いわゆるDLLでのエクスポートされた関数とは違う)と見なして呼び出すことができるようにしたものである。したがって、サーバーオブジェクトのプロパティやメソッドという形式を実現することができる。こうして、コンテナ(クライアント)アプリケーションからサーバーアプリケーションを操作することができるわけである。
ここからも容易に想像がつくように、OLEオートメーションの考え方はオブジェクト指向であり、オブジェクトのプロパティとメソッドを操作することが基本である。これは、まさにVisual Basicでのプログラミングにつながるものだ。実際、OLEオートメーションの構文はVisual Basicそのものである。つまり、Visual Basicの言語仕様ですべてのOLEオブジェクトをOLEオートメーションを通じて操作できるわけだ。
このOLEオブジェクトとは、アプリケーションだけではない。OSの持つ機能もすべてオブジェクトとして提供するというのである。この夢のOSはWindows NTの将来バージョンであるCairoからであるとMicrosoftは言ってきた。先ごろリリースされたCairo、すなわちWindows NT 4.0を見る限りは、まだ完全にそうはなっていないように思えるが、将来的にはWindows APIをまったく使わないでWindowsアプリケーションを作れるようになるハズだ。OLEオートメーションとは、別の言い方をすれば、Visual Basicの構文で書くことができるWindowsという自由度の高い巨大アプリケーションのマクロなのである。
もう、Windows APIを使うようなプログラミングは古いと述べたのはこのような背景があるからだ。これからは、OLEオートメーションですべてができる時代になっていくのだ。
こうしたOLEオートメーションの機能に加え、インプレイスアクティべーションでサーバーでの編集画面をコンテナ内部に表示し、サーバー側で発生したイベントをコンテナ側に通知するイベントのメカニズムを装備したのがOLEベースのカスタムコントロール、いわゆるOCXである。
このイベント通知のメカニズムは、実はOLEのコンテナとサーバーが逆転したような形で実現される。つまり、通常ならばサーバーが公開しているメソッドをコンテナが呼び出すのだが、イベントではコンテナが公開しているメソッドをサーバーが呼び出し、これがイベントとしてコンテナ側に認識される。
従来カスタムコントロールと言えば16bitのVBXを指すことが多かったが、この仕様は86系CPUの16bitでの使い方であるセグメントとオフセットという考え方に依存しており、32bitに対応することができないため、事実上なくなる運命にある。今後はカスタムコントロールと言えば、このOCXを指すことになるはずだ。
従来のVBXの動作とOCXの動作を比べてみると、そのままアーキテクチャーの新旧の比較ができる。
VBXでは、図のようにWindowsシステムからVisual Basicに送られてきたWM_XXXメッセージをそのまま、あるいはVB内部形式のVBM_XXXメッセージをVBXに送る。VBXでは必要な処理をしてVisual Basicのデフォルトコントロールプロシージャを経由してWindowsのデフォルトプロシージャに戻るという流れを取る。このように、VBXはあくまでもメッセージを使って処理が行われるオーソドックスなものだ。しかし、前述したようにSendMessageで送られるデータだけでは処理できるものに限界があるし、グローバルアドレスを参照して使うといった形になってしまう。
一方、OCXは構造的にもOLE 2.0のインターフェイスを使うものであり、LRPCを使ったプロシージャコールでアクセスするものだ。したがって、ここでも従来のメッセージベースでの制限を克服できるようになっている。また、プロシージャをコールするという形式が標準であることから、メソッドをカスタマイズすることができる。これも、従来のVBXではできなかったことだ。
OCXでもう一つ注意しておきたいのは、通常のOLEサーバーより高速に動作するという点だ。OLEサーバーには二つの種類がある。一つはアウトプロセスOLEサーバーであり、もう一つはインオブプロセスOLEサーバーである。
アウトオブプロセスOLEサーバーは通常EXE形式の実行ファイルであり、動作は通常のOLE 2.0のインターフェイスである。つまり、コンテナ側から見たら外にある別プロセスで動作しているサーバーである。
一方、インプロセスOLEサーバーは、コンテナが動作してるプロセスの内部にロードされて実行されるもので、通常はDLL形式のものである。インプロセスOLEサーバーのときにも、もちろんOLEのインターフェイスが使われるが、内部的に見るとスタック呼び出しの形でプロシージャをコールしている。したがって、実際にはプロセス間通信はしていないから、マーシャリングによるオーバーヘッドは軽減される。このため、アウトオブプロセスOLEサーバーに比較して、数百倍は高速に呼び出すことが可能である。OLEベースのミドルウェアとして注目されているOracle Objects OLEでも、このインプロセスOLEサーバーが採用されている。
OCXは、独立したアプリケーションではないから、実際にはDLL形式のOLEサーバー、すなわちインプロセスOLEサーバーになる。このため、高速にプロシージャコールをすることが可能なのである。
OCXが従来のVBXに比較して重要なのは、他の開発ツールからも使うことができるという点だ。たとえば、AccessやVisual C++などのMicrosoft純正ツールのみならず、Oracle Power ObjectsやBORLANDのDelphi(32bit版)などが挙げられる。先に述べたように、OCXはOLEベースであるから、すでに標準的にOSに取り込まれる方針となったOLEのメカニズムはサ−ドパーティも黙って見てはいられないのだ。OCXは、VBXのようなVisual Basicのためだけのものではなく、Windows標準のカスタムコントロールなのである。
パソコンに初めてBasicを搭載したのは、Bill GatesとPaul Alenだった。彼らはMicrosoftを作った。Microsoftは、Basicを売って大きく成長してきた。構造化されたBasic、統合開発環境のBasicを開発したのもMicrosoftだった。MicrosoftはGUI用の開発ツールとしてオブジェクト指向を取り入れたVisual Basicを作った。OLE2.0が不完全ながらも初めて実装されたのはVisual Basic 3.0だった。そして、MicrosoftはBasicをWindowsのマクロにしようとしている。GUIの仮面を持ったWindowsは、昔のパソコンがそうだったように、Basicで動くようになるのである。
このように、パソコンを使う限り、パソコンの主流OSがMicrosoftが作っている限り、MicrosoftにBill Gatesがいる限り、主流はBasicなのである。今、最新のBasicはVisual Basic 4.0だ。ということは、この業界の未来はVisual Basic 4.0にすでに見えているハズだ。
では、未来とはなんだろうか? 今見えているのは、リモートオートメーションである。これは、Visual Basic 4.0 Enterprise Editionにのみ装備された機能である。Visual Basic 4.0の持つオートメーションサーバーとのプロセス間通信を、同じマシンのみならずネットワークで接続された他のマシンとも行うことができるという機能だ。
この機能はWindows NT 4.0ではOSレベルでサポートされることが約束されている。このときの名称はネットワークOLEを使えば、ネットワーク上に分散したOLEオブジェクトを複数のマシンが共有することができる。つまり、一つのマシンの負荷を軽くしたり、さらには3階層のアプリケーション開発が可能になるのである。いわゆる分散オブジェクトOSとなるわけだ。
分散オブジェクトができたとしても、はたしてそれほどメリットがあるのだろうかという疑問もあるだろう。この機能はネットワークを前提としたものであるから、当然ながらスタンドアローンで使っている限りはメリットはない。
しかし、今はインターネットやイントラネットが注目を浴びる時代だ。RDBMSのデータをWWWサーバーを通じてWebブラウザで検索するというのも、3階層アプリケーションである。注目を浴びているJavaやVB Scriptは、WWWサーバーから送られてきたプログラムをWebブラウザで実行するというものである。このように、ネットワークといってもLANだけではない。インターネットが一般化してくれば、さらにLAN環境も普及するだろう。
こうしたときに起きる問題が、CPUの違うマシンが混在することだ。データや実行コードが違えば、制限も多くなってしまう。しかし、ここでWindowsやWindows NT以外のunixやMacintoshなどのマシンにもOLEが搭載されたらどうなるたろうか? OLEのマーシャリングメカニズムさえキチンと動けば、異なるマシン間でもデータの共有のみならず、OLEオブジェクトの共有が可能になるのである。
これが、Microsoftの描くOLEの、そしてVisual Basicの将来像だ。本当にそんな時代がくるのかは現在の段階ではなんとも言えない。AppleやIBM陣営が推し進めるOpenDocは、OLE以上にこのような分散オブジェクトを意識したアーキテクチャーである。どちらが主流になるのか、はたまたどこかで統合されるのが、現在のところ見えてはいない。
しかし、厳然たる事実としてあるのは、Visual Basic 4.0ではリモートオートメーションが可能になっており、Windows NT 4.0のβにもその機能は搭載されているということだ。
未来のことは、もうちょっと後で知ればいい。今は、Visual Basic 4.0からOLEオートメーションを使って、その未来をかいま見てみようではないか。