これは、BeBook日本語化プロジェクトの一環として、Be Inc.の発表したApproaching Beを日本語訳したものです。文書はできる限り正確を期したつもりですが、もし内容に不備があるようでしたら、訳者の長田までお知らせいただければ幸いです。本ページの訳文に関する文責はすべて長田正彦にあります。
なお、BeOS(TM)のアーキテクチャやAPI,BeOS Kit,BeOS Serverに関するより正確な情報を知りたい方は、BeBookをご覧下さい。



Approaching Be

BeOSのためのプログラミングへの序論



Be Operating System(BeOS)がコンピューティングの世界へ登場して以来、何千ものソフトウェア開発者がその特徴の数々や単純さ、そしてパフォーマンスに引きつけられてきました。 この関心は、PowerMacintoshやそのクローンといった、メインストリームのPowerPCシステム上で動く移植版BeOSの導入によって拡大されてきました。 関心が上がるにつれて、我々が最も頻繁にプログラマから受けとる質問の一つに、「どこから始めればよいのでしょうか?」というものがあります。

BeOS向けのプログラミングは、少くとも「最新の」ものだと考えられている他のオペレーティング・システム向けのプログラミングと比較した場合、多くの点で似ています。 しかし、設計と目標に基本的な違いがあるため、あなたがアプリケーションを組み立てる方法に影響を及ぼすかも知れません。 プログラマは自身のコードを書き始める前に、OS設計上の基本的な目標と哲学を理解したいと思うものです。

この白書は、一連の基礎的な質問に答えるために考えられました。 これはプログラマを念頭に置いて書かれていますが、プログラマでない人の中にも、同様に有益だと思う人がいるかもしれません。 また、これはMacOSやWindowsの環境からBeOSへやって来るプログラマにとって有益である事をも目論んで書かれています。 話題の多くは、BeOS上でのアプローチを、こうした他のシステムで用いられるアプローチと比較する方法で検討されます。

内容は、三つの節に分かれています。 始めの節では、BeOSの根底にある基本的な設計と哲学を検討し、それらがどのようにあなたのソフトウェアの設計に影響を与えるかを検討します。 二番目の節では、BeOSの全体的な構造について検討し、プログラマが扱う重要なコンポーネントを確認します。 三番目の節で、我々は、基礎的で単純なアプリケーションの作成をざっとやってみます。

この文書を補強する幾つかの白書や入門書が利用可能です。 これらは、Beウェブ・サイトhttp://www.be.comDeveloper sectionで見つける事が出来ます。

[注: この手引のためのソース・コードは、ftp://ftp.be.com/pub/Samples/approachingBe.tgzで見つけられます。]


基本的な概念

BeOSを生み出す過程で、Beエンジニアリング・チームは、一組の基本的な仮定と概念をガイドとして使いました。 これらの概念は、OS内に深く浸透しているため、あなたが自身のアプリケーションを構築する方法に重要な影響を与えるかもしれません。 あなたが、MacOS空間からBeOSに接近しているにせよ、或いはWindows空間から接近しているにせよ、BeOSがこれらの[OSの]基本コンセプトの根底にある多くの違いのどこで異なっているのかを理解する事は同じく重要です。

Be社のオフィス周辺での共通な冗談の一つに、「BeOS」という言葉は、「流行語を実現したオペレーティング・システム」を意味するものだ、というものがあります。 疑いなく、BeOSは、市場で「最新の」オペレーティング・システムが実現すべきと考えられている期待に合致し、それを上回っています。 これらの流行語で表現される概念のうちの五つについては、BeOS向けに書かれたソフトウェアの設計に影響を与えるため、理解しておく事が重要です; すなわち、オブジェクト指向、プリエンプティブ・マルチタスキング、保護メモリ、対称型マルチプロセッシングおよび広範囲にわたるマルチスレッディングです。

オブジェクト指向

多分、BeOSと現在主流のオペレーティング・システムの最も本質的な違いは、BeOSがオブジェクト指向オペレーティング・システムであるということです。 これが意味する事は、アプリケーション・プログラミング・インタフェース(API)は、あなたがMacOSやWindowsで見つけるであろうプロシージャ・コールではなく、オブジェクトで構成されているという事です。 あなたがBeOS向けにアプリケーションを作成する場合、あなたは基礎的なBApplicationオブジェクトの派生物を作成する事になり、あなたはBeOS組み込みのBWindowやBButtonといった標準オブジェクトも、こうしたオブジェクトからの派生物も使う事になります。

オブジェクト指向プログラミングは、登場以来しばらく経っているのですが、ソフトウェア開発にその基礎的な概念が利用されるようになったのはつい最近の事です。 BeOSは、完全にオブジェクト指向概念を根底に置く、数少ないオペレーティング・システムの一つです。 BeBookという、完全なBeOS APIを記述した参考本を見ても、あなたは一組のプロシージャも見つけられないでしょう。 あなたが見つけるものは完全なアプリケーション・フレームワークであり、これはアプリケーションを作成するために組み合わせるオブジェクト群からなり、ウィンドウとインタフェースを生成し、ネットワーク接続を管理し、あなたのアプリケーション内で生成される大部分のデータ・オブジェクトを操作します。 これらのオブジェクトは、膨大な組み込みの機能を含み、あなたがゼロから始めたり、複雑なチェーンに個別のプロシージャを接続したりする必要を無くしています。 多くの基礎的な仕事が、あなたのためにすでになされています。 そしてさらに、あなたは他のBeOSプログラマによって作成されたオブジェクトを、あなたのアプリケーション内で使うことも出来るでしょう。

しかし、これが意味する事は、BeOS内では、あなたはオブジェクト指向言語でプログラムする必要があるという事です。 BeOSのAPIは、C++に基づいています。 Javaという、C++によく似た親戚も、将来サポートされる事になっています。 Beがこれらの言語を選択したのは、それらが業界標準に基づいており、広範囲にわたるベンダの支持を得ているためです。

あなたがオブジェクト指向概念を理解しており、C++を使った事があるならば、BeOSに飛び込んでくるのに何の問題もありません。 あなたがMacOS上でプログラムをした経験があり、メトロワークスのPowerPlantやアップルのMacAppのようなアプリケーション・フレームワークを使った事があるのであれば、BeOSのAPIはあなたに非常になじみがあるように見えるので、更によい位置にいると言えます。 同様に、あなたがWindows用のMicrosoft Foundation Classを使った事があるのであれば、BeOSの中で見つける概念の多くが分かるでしょう。

あなたがC++やJavaを知らないけれど、オブジェクト指向プログラミングについて学びたいというのであれば、BeOSは新しく、比較的すっきりしたオペレーティング・システムであり、オブジェクト指向概念に基づいて組み立てられているので、出発点として優れた場所です。 従って、あなたは他のシステムで見つけるかもしれない様な、APIに対する多くの例外と回避方法を取り扱う必要がないでしょう。

プリエンプティブ・マルチタスキング

大部分のプログラマは、マルチタスキング−一度に一つ以上のアプリケーションを走らせて、それらに対するCPU時間の割り当てについては、オペレーティング・システムに悩んで貰う機能−に精通しています。 プリエンプティブ・マルチタスキングは一歩進んだ概念であり、特にあなたがMacOSからやって来ているならば、両者の違いを理解することは重要です。 MacOSを含む、いくつかのオペレーティング・システムは、コオペラティブ・マルチタスキング、つまり個々のアプリケーションが、他のアプリケーションの実行を続けられるようにするために、自発的に【占有】時間を放棄しなければならないことを意味するものとして知られている機構を使います。 MacOS内では、この機構はWaitNextEvent()プロシージャ・コールによって表現され、他のイベントが見つかるまでOSに制御を戻します。 もちろん、アプリケーションがWaitNextEvent()をコールしないか、或いはコールするのが遅れた場合には、他のアプリケーションは、スムーズに実行するのに問題が生じる可能性があります。

プリエンプティブ・マルチタスキングは、WaitNextEvent()のようなものの必要性を取り払います。 BeOSの様なプリエンプティブ機構においては、個々のアプリケーションがある特定の期間実行するかどうかをオペレーティング・システム自身が許可し、これは個々のアプリケーションの優先順位と、システム内で実行されているタスクの数に依存します。 時間が尽きると、BeOSはたとえ何をしていても、【現在実行中の】アプリケーションを止めて、次のプロセスへ制御を渡します。 この結果、ユーザにとってよりスムーズで対話性に富んだシステムとなっています。

もちろん、これが更に意味することは、プログラマであるあなたは、あなたのアプリケーションがいつでも中断される可能性がある、という事を忘れないでいる必要があるということです。 通常、あなたはこの機構下で特別に違う事をする必要はありません。 しかし、あなたが共有された資源にアクセスしている場合、その資源を共有している他のプロセスが、あなた【のアプリケーション】が「停止」状態にある間に飛び込み(或いは出て行き)、それがあなたに影響を及ぼす可能性があります。 コオペラティブ・マルチタスキングと違って、OSがあなたのコードを切り替えてしまう前に、あなたが一連の命令を終える事が、必ずしも保証されているわけではないということを覚えておいて下さい。 特定のタスク(リアルタイムオーディオやビデオなど)の重要度がどれ位かをOSに通知する方法は存在しており、必要であれば資源をロックする方法があります。 我々は、程なくそれについて検討します。

保護メモリ

ユーザがパーソナル・コンピュータ・システムについて持つ重要な不満の一つに、アプリケーションがクラッシュし、そうなる事により、マシン全体が固まってしまう事が如何に多いか、というものがあります。 これは、通常失敗したアプリケーションが、他のアプリケーションやオペレーティング・システム自身の占有する物理的なメモリを書き換えようとする事が原因となっています。 これらの変更は、システム内に波及し、アプリケーションと全マシンをクラッシュさせる事になります。

これを防ぐために、BeOSは保護メモリとして知られる機構を使います。 これが意味することは、あるプロセスによって占有されたメモリは、他の如何なるプロセスからもアクセス出来ないということです。 アプリケーションがBeOSの下で起動する時、それは完全な論理アドレス空間(現在は32ビットあるいは4GBのメモリ)すべてを保有する様に指示されます。 BeOS下のアプリケーションは、ポインターや他の直接的なメモリ参照を用います。 あなたがWindowsからやって来ているならば、相当に時代遅れのやり方だと思うかも知れませんが、MacOSの場合は、メモリ管理を考慮に入れるために、しばしば間接的なメモリ「ハンドル」を使います。

もちろん、大部分の実世界のコンピュータには、4GBものメモリはインストールされていません。 したがって、BeOSは各アプリケーションのメモリの使用状況を密接に見張ります。 それは全部で4GBのメモリ空間を「ページ」に分割し、続いてどれだけのページが使われており、各ページにどれ位アクセスがあるのかを追跡します。 他のプロセスが追加の物理メモリを必要とすると、BeOSは幾つかの使用頻度が最も少ないページを一時的にディスクにアンロード【退避】する事によって余裕を作り、再び必要になった時に、それらのページをリロード【メモリへ再読み込み】します。 これが、「仮想記憶」の背後にある本当の意味です。 BeOS内では(UnixやWindows NTなど、最新のオペレーティング・システムと同様に)、仮想記憶は常に働いています。

保護メモリは、長時間システムを安定に保持します。 あなたがアプリケーションかサーバー、或いは多くの他のコードを書いているとしても、システムをダウンさせることは困難でしょう。 これ【システムの安定性】に対する理由の他の一つは、BeOSが「クライアント-サーバー」構造に基づいているという事であり、スクリーンやネットワーク用ハードウェアといったシステム資源は、複数の「クライアント」がアクセスを得るために対話する「サーバー」によって制御されているというものです。 全てのアプリケーションは、この構造のクライアント側に位置します。 この機構により、資源の衝突を最小化し、より高次元の保護が提供されます。 あなたがハードウェア・ドライバの様な、アーキテクチャのサーバー側に位置するコードを作成している開発者の一人であるならば、あなたはあなたのコードが単純で、速く、防弾仕様であることを確かめておく必要があります。 BeBookは、こうした種類のソフトウェアの構築に対して、更なるアドバイスを提供します。

対称型マルチプロセッシング

今日の主流オペレーティング・システムの多くにとっての他の重要な制限は、システム当り一つのマイクロプロセッサしか存在しない、という仮定です。 MacOSの様に、二番目のプロセッサを限定的に使用することが出来るシステムも存在しますが、大部分のOSはマルチプロセッシングを念頭に置いて設計されませんでした。

BeOSは、当初からマルチプロセッサOSとして設計されました。 それ【BeOS】を生み出した初期のシステムは、全て二つのマイクロプロセッサを使用しており、現在では、BeOSは1〜4プロセッサを搭載したシステム上で動作します。 BeOS自身には制限は無く、理論的に「n」プロセッサをサポートすることができますが、現実的には、今現在の主流ハードウェアの実装上では、8プロセッサを超えるところで顕著な限界があります。

さらに、BeOS内のマルチプロセッシングの実装は「対称型」です。 プログラマとして、あなたはある特定の時点で、自身のアプリケーションがどのプロセッサを使用しているかについて心配する必要はありません。 BeOSアプリケーションを設計する上で、あなたは単一プロセッサのシステムで実行するためのものと8プロセッサシステムのものとで違った事をする必要はありません(特定の計算が主体となるものの場合には、最適化の目的のため、プロセッサ数を考慮に入れたい場合があるかも知れませんが)。あなたのアプリケーションは単一プロセッサで起動し、他のプロセッサへ移動し、実行中何度も【元のプロセッサに】戻って来ます。 こうした事全てが、あなたのコードに対して透過的です。

しかし、対称型マルチプロセッシングが意味する一つの事は、あなたが並列に多くの(多くの、多くの)事を行うアプリケーションを作成する事が出来るということです。 そして、これをするために、あなたが念頭に置く必要のある最後の一つとなるBeOSの概念があります...

広範囲にわたるマルチスレッディング

伝統的なオペレーティング・システム内では、個々のアプリケーションは、コードの頭から実行の終了までを単一の「スレッド」であると見なす事が出来ます。 あなたが複数のアプリケーションを立ち上げた場合、複数の実行スレッドが一度に存在し、それらは(複数の)プロセッサ時間を共有します。

BeOS内では、スレッド化はさらに先を行っています。 複数プロセッサの利点を最大限に利用するために、各アプリケーションは、複数の実行スレッドに分割される必要があります。 アプリケーションが単一スレッドしか持たないならば、それは一度に一つのプロセッサ上で実行しなければなりません(実行途中でプロセッサ自体は別のものに変るかも知れませんが。) しかし、アプリケーションが複数スレッドを持つならば、そのアプリケーションは複数プロセッサを並列に使用することができます。 これは、コードの実行時間を劇的に改善することができます。

様々なな実行モデルをテストする過程で、我々は、アプリケーションを複数のスレッドに分割することにより、全体としての実行とタスク切り替えを、単一プロセッサのシステム上でさえも、よりスムーズでより速く出来る、という事を発見しました。 広範囲にわたるスレッディングが、プリエンプティブ・マルチタスキングの効果を助け、増幅する事が分かったわけです。

これを知って、BeOS自身は何重にもスレッド化されました。 完全な停止状態においてすら、BeOSは何十ものスレッドを使用します。 システムの中のあらゆるサーバーは、絶えずスレッドを生みます。 さらに言えば、スレッド化されないアプリケーションを書く事は事実上不可能なのです。 BApplicationオブジェクトを生成する際に、二つのスレッドがあなたのために自動的に生成され、BApplicationオブジェクトによって管理されます(あなたは、アプリケーション・オブジェクトを使う以外に何もする必要がありません。) BeOSの中のあらゆるウィンドウは、二つのスレッドを生成し、従ってあらゆるウィンドウは理論的には別のプロセッサ上で実行可能です。 マルチスレッディング、対称型マルチプロセッシングおよびプリエンプティブ・マルチタスキングはすべて相互に関連しており、この相乗効果がBeOSに持てるパワーの多くを発揮する事を可能にしています。

BeOSのオブジェクト指向という性質以外には、恐らく、マルチスレッディングが、ソフトウェア設計に対して最も本質的な影響を持ちます。 幸運な事に、オブジェクト指向とスレッディングは、手に手をとって進みます。 もしあなたがMacOSか、またはWindowsからBeOSにやって来ているのであれば、スレッド化を含む二つのことを念頭に置いておく必要があります;

  • 各スレッドを「イベントループ」とみなしてください
    MacOSとWindowsの双方は、実世界(マウス-クリック、キー・プレスなど)からの全てのイベントが通過するアプリケーション・イベントループの概念を使っています。 あなたは、BeOS内部での個々のスレッドを独立したイベントループとして考えることができます。 これが意味する事は、各アプリケーションは、ただ一つではなく、複数のイベントループを持つという事です。 BeOS内では、ウィンドウ内でのマウスクリックはアプリケーション全体を司るイベント・ループを通り抜ける訳ではなく、それは直接ウィンドウ・スレッドに届けられます。 これが更に意味する事は、アプリケーションが一度に複数のイベントを処理する可能性があるという事です。 少し複雑に聞こえますが、これは実際にはとても単純であって、その理由は、オブジェクト指向システムの内部では、各オブジェクトは自分自身のイベントについてのみ心配すればよいからです。 従って、コードは通常単一のイベントループ・システムよりも、ずっと単純ですっきりしています。今度は、上の段落で、「イベント」という単語を「メッセージ」という単語で置き換えて下さい。
  • BeOS内部では、「イベントループ」を「メッセージ・ループ」と呼びます。 こう呼ぶ理由は、各スレッドが、単なる一組の、実世界のマウス・クリックとキー・プレス以外のずっと広範囲なメッセージを扱うことができるからです。 あなたは、BeBookBLooperBHandlerオブジェクトについて読む(そしてどのオブジェクトがこれらから継承しているのかを見る)事により、スレッドに関する更に詳しい情報を得られます。また、BMessageBMessengerオブジェクトについて見る事で、メッセージに関するより多くの情報を得られます。

  • あなたはオブジェクトを「ロック」する必要があるかもしれません複数のスレッドが意味することは、複数の事象が同時に発生する可能性があるということです。あるオブジェクトが、BWindowオブジェクトの要素である値を変更しようとしたのが、BWindowが自身を描画している時と同時だったら、どうなるでしょう?結果は非常に興味深いと思われます。あなたはこうした衝突を割けるために、使用中のオブジェクトを必要に応じてロックし、後でアンロックする事が出来ます。ロックをしている間中、一つのプロセスだけが、あるオブジェクトに排他的にアクセスする事が可能です。あなたの様な、スレッディングに馴染みのある人にとっては、これは「セマフォ」の概念に非常によく似ていると感じられるでしょう。あなたは正しくて、これらはまったく同一のものです。ロックに関しては、BeBookBLockerオブジェクトを見ると、更に詳しい情報を得られるでしょう。



システム・アーキテクチャ

BeOSの根底をなしている基礎的な概念を記述した今、我々はより具体的な方法で、システムの構造を概説することが出来ます。 下のブロック図は、BeOSの構成要素の概要を示しています;

BeOSは、三つの主なコンポーネントのグループに分ける事が可能です; カーネル、BeOSサーバーそしてBeOSキットです。

カーネル
BeOSは、ハードウェアを抽象化して、基礎的なOSサービスを提供するためにマイクロカーネルを使用します。 あなたが多分期待するように、BeOSカーネルは複数プロセッサの特徴を最大限に活かし、なおかつ大量の同時に実行するスレッドを扱うために最適化されています。 カーネルの機能は、ソフトウェア・ドライバーを利用する事によって拡張可能であり、これらはシステムの要求に応じて、動的にロードされ、アンロードされます。

BeOSサーバー
ずらりと並んだソフトウェア・サーバーは、アプリケーションやOS自身によって利用される重要な領域をカプセル化し、BeOSの中核を成します。 これらのサーバーの例としては、グラフィックス・サービスを提供するApp Server、ファイルシステムとデータベース機能を提供するStorage Server、TCP/IP機能を提供するNetwork Server、そして多様な音源からのリアルタイム・オーディオストリームを制御するAudio Serverといったものがあります。 これらのサーバーは、システムの起動時に自動的に起動され、クライアント・サーバー・モデルを中心に設計されており、それら自体が何重にもスレッド化されます。

BeOSキット
アプリケーションは、BeOSサーバーに決して直接アクセスしません。 より正確に言えば、アプリケーションは、BeOSキットを利用するのですが、これらのキットは、順番にどうやって個々のサーバーとやり取りするかを知ります。 それぞれのキットは、一組のC++オブジェクトから成り立っており、これらを使用したり、サブクラス化する事が可能です。 これらのオブジェクトは、サーバーを順にコールし、より複雑なタスクを達成します。 BeOSキットの例としては、ほとんどのウィンドウやビュー、および描画機能を制御するインターフェース・キットや、アプリケーションレベルでの機能や通信を制御するアプリケーション・キット、オーディオやビデオ機能を制御するメディア・キットといったものがあります。 こうした一連のBeOSソフトウェア・キットは、広範囲のクラスや機能を提供し、アプリケーションは複雑な機能を構築するために、これらを使用します。 これらのキットは、絶えず拡張されていて、Beによって、BeOSの各リリースを通して改善されています。

BeBookで見つかる、中核のBeOSソフトウェア・キットの例としては、以下のものが含まれます;

アプリケーション・キット
アプリケーション・キットは、BApplicationBMessage(通信用)あるいはBLooper(新しいスレッドの生成用)といった中核となるアプリケーション・オブジェクトを含みます。

ストレージ・キット
BeOSの重要な利点の一つに、これがファイルシステム機能と統合化されたデータベース機能の両方を提供する、という点があります。 ストレージ・キットは、ストレージ・サーバーと共に動作して、BFileBDirectoryおよびBDatabaseといったオブジェクトを提供します。

インターフェース・キット
キットの中でも最大のものであるインターフェース・キットは、アプリケーション・サーバーと共に動作して、BWindowBViewのようなオブジェクトを提供しますが、これらのオブジェクトは、BListViewBCheckBoxBTextView、およびその他の多くのインターフェース・オブジェクトに対する基盤を提供します。 インターフェース・キットも(BViewを通じて)全ての描画機能をカプセル化します。

メディア・キット
メディア・キットは、システム全体を通して、リアルタイムのデータ・ストリームを制御しますが、これが意味する事は、オーディオやビデオのストリームを扱うのはキットである、ということです。 このキットは、BAudioSubscriberの様な、複数プロセスが単一のデータストリームにアクセスし、操作するのを許可するオブジェクトを通じて、「購読者」モデルを使用します。

ミディ・キット
このキットが提供するのは一組のクラスであり、これはMIDIメッセージを翻訳したり、組み立てたりする方法を知っており、ハードウェアMIDIドライバから【のデータを】受け取ったり、送り出したり、あるいは組み込みのMIDIシンセサイザーと通信する事が可能です。

デバイス・キット
このキットが提供するのは、ドライバの構築用に一般化されたインタフェースであり、これはハードウェア・ドライバやグラフィックス・ドライバやその他といった、カーネルの機能を拡張します。 これには、BSerialPortの様なオブジェクトも含まれます。

ネットワーク・キット
ネットワーク・キットは、バークレー・ソケット(BSD)モデルに基づいたTCP/IPサービスを提供します。 これは、電子メールの送受信方法を知っているクラスも提供します。

3Dキット
3Dキットは、三次元レンダリング・エンジンおよびクラスを提供し、これによって開発者は、容易に対話性のある三次元グラフィックスを構築し、操作する事が出来ます。 このキットは将来、OpenGL標準を取り入れるために拡張される予定です。

サーバーとキットは密接に共に働き、ほとんどの場合、キットは単なるインターフェースであって、アプリケーションは、これを経由してサーバーに対するリクエストを作ります。 例えば、描画メソッドの実行中、あなたはウィンドウに線を描画します;

この場合、あなたは、自身のコード中でBViewオブジェクトを生成します(BViewsはスクリーンの上あらゆる描画や、もしくはオフスクリーンでのそういった事【あらゆる描画】に対して責任があります。) 各ビューはDraw()メソッドを持ち、あなたはビューに区別可能な見た目を与えるために、これを記述します(そのビューが独特のものでないなら、あなたは単に、インターフェース・キット内の標準的なビューオブジェクトを利用し、Draw()メソッドを書くことを忘れても構いません。) Draw()メソッドは、線を描画するために、組み込みのStrokeLine()メソッドをコールします。 StrokeLine()は、実際にはApp_Serverにメッセージを送り、それに線を描画して貰い、その後直ちに実行環境に制御を返します。 あなたのビューにあるDraw()コードの次の行を実行している間、App_Serverは、スクリーン・バッファを変更するために、適切なドライバ(例えば、ハードウェア内にアクセラレーション用のコードがあるかも知れません)をコールする事により、線を描画する事に専念(マルチスレッディングの概念が、ここで再び登場します)しています。

このように、BeOSキット中のオブジェクトは、BeOSサーバーに対応します。 ここにあげたのは、いくつかのキットと、それらが通信する対応サーバーです;

アプリケーション・キット App_Serverとカーネル
ストレージ・キット Storage_Server(ファイルシステム)
インターフェース・キット App_Server
メディア・キット Audio_ServerとVideo_Server
ミディ・キット Audio_Server
3Dキット App_Server
カーネル・キット カーネル
デバイス・キット カーネル
ゲーム・キット App_Server
ネットワーク・キット Net_ServerとMail_Daemon

BeOS概念の土台を築いた今、それらがどのように調和しているのかを理解する最良の手段は、アプリケーションを書くことです。 このために、我々は単純なアプリケーションである、HelloWorldのBeOS向け実装について見てみます。 次のセッションの検討においては、あなたがC++の基礎を理解していると仮定します。



HelloWorldアプリケーション

HelloWorldは、幾つかの単純な事をします。 それは、起動時にウィンドウを生成します。 そのウィンドウ内に、「Hello, World!」という文を書きます。 HelloWorldは「...について」アイテムと「終了」アイテムを持つメインメニューも生成します。 メインメニューからAboutを選択すると、標準のアバウトダイアログを表示します。 メインメニューから終了を選択するか、またはウィンドウを閉じると、アプリケーションは終了します。

我々がこのアプリケーションを作成する際に分かる事は、大部分の仕事が、我々のために、基礎的なBeOSオブジェクト内ですでになされている、ということです。 我々は、個々のオブジェクトを、ヘッダ・ファイルとインプリメンテーション・ファイルで定義していきます。 このような単純なアプリケーションでは、我々は近道をして、コードをほんの少しのファイルにまとめる事が可能ですが、ここでの目的は、HelloWorldを、あなたが実用的なアプリケーションを書く時と同様な方法で書く事にあります。

最初に、我々はアプリケーション・オブジェクトを生成する必要があります。 このオブジェクトへのインタフェースは単純です;

// -----------------------------------------------------------------------
// HelloWorldApp.h
// -----------------------------------------------------------------------
     #pragma once

     #include <Application.h>

     class HelloWorldApp          : public BApplication
     {
          public:
               HelloWorldApp();
     };

#pragma once行は、あなたが作成するあらゆるヘッダ・ファイルの先頭に置いておく必要があります。 CodeWarriorは、これを利用して、ヘッダがたまたま二度インクルードされたりしないことを確実にします。 これは、同様の機能を果たすために利用される#defineや、#if及び#endif宣言よりも単純ですが、#pragma onceは開発システム相互の移植性の点で劣ります。

次の行は、BeOSのBApplication定義をインクルードします。 HelloWorldAppは一般的なBApplicationオブジェクトのサブクラスであるため、我々はこれらの定義をインクルードする必要があります。

HelloWorldAppクラスは、次の行で定義されており、非常に単純です。 HelloWorldAppは、BApplicationのサブクラスです。 それは、BeOSアプリケーションの通常の動作全て、つまりメインメニューやアバウトボックスや終了コマンドを含むものを継承します。 それは、アプリケーション自身のために、メインスレッドも継承します。

この単純な例では、新しいメソッドは一つだけあって、それはこのクラスに対するコンストラクタであるHelloWorldApp()です。 我々は、このコンストラクタを、アプリケーションのウィンドウを生成するために使います。 HelloWorldAppのインプリメンテーション【ファイル】も、同じく単純です;

// -----------------------------------------------------------------------
// HelloWorldApp.cp
// -----------------------------------------------------------------------
     
     #include "HelloWorldApp.h"
     // 他のインクルード文はここに入る

     main()
     {
          HelloWorldApp*     myApplication;
          myApplication = new HelloWorldApp();
          myApplication->Run();
          delete myApplication;
          return 0;    
     }


     HelloWorldApp::HelloWorldApp()     : BApplication('HLWD')
     {
          // ウィンドウと中身をセットアップする
     }

明快さのために、我々はウィンドウ生成コードをコメントアウトしました。 我々は、一分後にそれ【ウィンドウ生成コード】に到達します。 あらゆるCやC++のアプリケーションと同様に、main()ルーチンは必要です。 この場合、あなたのアプリケーションがどんなに複雑になっても、main()は単純で、ほとんど同じ様に見えます。main()は、「HelloWorldApp」型のアプリケーションにポインタを割り当て、続いて次行でアプリケーション・オブジェクトを生成します。 次いで、アプリケーションはRun()を送ることで起動します。 Run()はアプリケーションのメインスレッドを実体化し、アプリケーションが終了するように命令されるまで、実行環境に制御を返しません。 それ【終了命令を受ける事】が起きると、main()myApplicationオブジェクトを削除して、完全のために全【実行】過程の結果として0を返します(この最後の行は、絶対に必要だという訳ではありません。)

インプリメンテーション【ファイル】中のこの他のルーチンは、HelloWorldApp()コンストラクタだけです。 HelloWorldAppBApplicationから派生されているので、我々はBApplicationのコンストラクタを実行し、【コンストラクタに】アプリケーションのクリエータ署名である『HLWD』を送る事を許可します。 我々は、HelloWindowオブジェクトを定義した後で、このコンストラクタ【に関する検討】に戻ってきます。

我々が生成する必要があるウィンドウは、実際には二つのオブジェクトから構成されます。 ウィンドウ自体、およびウィンドウ内で「Hello, World!」というテキストを描画するビューです。 我々は、この梯子のふもとから出発して、最初にビューを定義します。

// -----------------------------------------------------------------------
// HelloView.h
// -----------------------------------------------------------------------
     #pragma once

     #include <View.h>

     class HelloView          : public BView
     {
          public:
                                    HelloView(BRect frame, char* name);
               virtual     void     AttachedToWindow();                   //オーバーライド
               virtual     bool     Draw(BRect updateRect);               //オーバーライド
     };

// -----------------------------------------------------------------------
// HelloView.cp
// -----------------------------------------------------------------------
     #include "HelloView.h"

     HelloView::HelloView(BRect frame, char* name)
                    : BView(frame, name, B_FOLLOW_ALL, B_WILL_DRAW)
     {
     }

     void
     HelloView::AttachedToWindow()
     {
          SetFontName("Times New Roman");
          SetFontSize(24);
     }

     void
     HelloView::Draw(BRect /*updateRect*/);
     {
          MovePenTo(10, 30);
          DrawString("Hello, World!");
     };

ヘッダの中で、HelloViewは一般のBViewオブジェクトのサブクラスとして定義されます。 BeOS内には、BViewから派生するオブジェクトが無数に存在します−スクリーン上に描画する物は殆どがBViewオブジェクトであり、これはBViewがそのような目的で設計されているからです。 BViewsも、他のビューを含む事が可能です。 定義の中で、我々はコンストラクタを提供し、さらに−いわゆる「オーバーライド」によって−BViewによって定義される二つのメソッドを再定義します; AttachedToWindow()Draw()です。

インプリメンテーション【ファイル】中で、我々は空のコンストラクタを提供しますが、これはBViewコンストラクタに引数を渡す目的を持っています。 我々は、BRect矩形オブジェクトとして供給される、ビューのフレームと、ビューの名前(これはもっと複雑なアプリケーションで、ビューを検索し、操作するのに使う事が出来ます)を渡します。 我々は、この他に二つの引数も渡します。 一つめのB_FOLLOW_ALLは、ウィンドウの大きさが変更された場合にはいつでも、HelloViewに自分自身【のサイズ】を属するウィンドウに合わせる様に命令します。 こうすることによって、我々はウィンドウの変更について気にする必要が無くなり、根底のBViewオブジェクトはこの機能を組み込みのものとして持ちます。 二番目のパラメータであるB_WILL_DRAWは、ビューが属するウィンドウに、HelloViewは(単に他のビューに対するコンテナに対してではなく)スクリーン上に描画するという事を通知し、【このB_WILL_DRAWは】スクリーンのアップデートが必要になったら、必ず通知されなくてはなりません。

AttachedToWindow()は、ビューがウィンドウに「付与され」る時にコールされるメソッドです。 AttachedToWindow()は、BeOS内で「フック」メソッドと見なされます−デフォルトでは何もしませんが、ビューが付与された時、我々がそれのセットアップを終えるためにオーバーライド出来る様に、提供されます。 HelloView内では、我々は単にビューに対してフォントとフォント・サイズを設定したいだけです。

Draw()は、もう一つの「フック」メソッドです。 この場合、Draw()は、スクリーンに変更が生じ、結果的にビューがその内容を書き直す必要が生じた場合には、いつでもコールされます。 大部分のBViewから派生したオブジェクトは、Draw()をオーバーライドします。 引数updateRectは、アップデートの必要がある領域を提供します。 この場合、内容が単純で、直ぐに再描画出来るので、我々はこの引数を無視しても構いません。 我々が、単純にビューのペンを(10,30)【という座標位置】に移動して、文字列「Hello, World!」を現在のフォントと(前もってAttachedToWindow()でセットされた)フォントサイズを使って描画します。

こうして我々はビューを定義したので、ウィンドウを定義することができます。

// -----------------------------------------------------------------------
// HelloWindow.h
// -----------------------------------------------------------------------
     #pragma once

     #include <Window.h>

     class HelloWindow          : public BWindow
     {
          public:
                                    HelloWindow(BRect frame);
               virtual     bool     QuitRequested();             //オーバーライド
     };

// -----------------------------------------------------------------------
// HelloWindow.cp
// -----------------------------------------------------------------------
     #include "HelloWindow.h"
     #include "HelloView.h"

     HelloWindow::HelloWindow(BRect frame)     
                 :BWindow(frame, "Hello", B_TITLED_WINDOW, B_NOT_RESIZABLE)
     {
          BRect       viewRect = Bounds();
          HelloView*  theView = new HelloView(viewRect, "HelloView");
          AddChild(theView);
          Show();
     }


     HelloWindow::QuitRequested()
     {
          be_app->PostMessage(B_QUIT_REQUESTED);
          return true;
     }

HelloWindowクラスは、派生元のBWindowクラスには無い独自の性質を二つだけ持ちます; コンストラクタと、QuitRequested()フックメソッドをオーバーライドしたものです。

コンストラクタの中で、我々は継承されたBWindowコンストラクタに引数を渡します。フレームは、ウィンドウがスクリーンの上にどこに置かれるのかを決めます。 「Hello」がウィンドウのタイトルで、ウィンドウのタイトルバー(もし【タイトルバーが】あればですが、この場合には確かにあります)で使われます。 B_TITLED_WINDOWはウィンドウの種類を、普通の、移動可能な、上部にタイトルバーが付いたものとして設定し、B_NOT_RESIZABLEはウィンドウサイズを固定して、変更不可にします。

コンストラクタ自体の内部で、我々はHelloViewオブジェクトを生成します。 ビューの正しいサイズを受け取るために、我々は組み込みのBounds()メソッドをコールすることによってHelloWindowの境界矩形を得る事が出来ます。 続いて我々は、ビューをウィンドウ内に貼り付けるために、ウィンドウのAddChild()メソッドをコールします。 最後に、我々はShow()をコールすることによってHelloWindowを可視化します。

BeOS内部では、それぞれのBWindowオブジェクトは、自分自身のスレッドの中で動作します。 これが意味することは、あなたがBWindowオブジェクトを生成する度に、背後ではメッセージ・ループが生成され(BWindowBLooperから派生しています)、これが自動的に起動されるという事です(この様に、我々は明示的にRun()をコールする必要はありません。) ユーザがウィンドウの「go-away」ボックス上でクリックするとき、本質的に、我々はウィンドウスレッドを終了します。 それで、ユーザがウィンドウを閉じる時にはいつでも、QuitRequested()がコールされます。 BWindowの場合、QuitRequested()はデフォルトでtrueを返し、ウィンドウを消去します。

我々の例では、もう一つやっておきたい事があります。 ユーザがウィンドウを閉じる場合、我々もHelloWorldアプリケーションに終了して欲しい訳です。 よって、我々はQuitRequested()をオーバーライドします。 アプリケーションに終了を指示するには、幾つかの方法があります。 この場合、我々はアプリケーションにB_QUIT_REQUESTEDメッセージをポストします。be_appは、どんなアプリケーションの内部でも使え、単にアプリケーションオブジェクトを指し示すだけのグローバル変数なので、我々はbe_appをPostMessage(B_QUIT_REQUESTED)に対して使うことができます。 新しい終了メッセージがウィンドウ・スレッドからアプリケーション・スレッドに送られます。 我々は、BWindowから継承されたHelloWindowの性質を使って、適切にウィンドウを閉じ、ウィンドウスレッドの終了を終えるために、trueを返す必要があります。 同時に、アプリケーションは我々が送った終了メッセージを拾っており、全アプリケーションをシャットダウンし始めています。 この場合は大した事がありませんが、この並列性はBeOSの重要な部分であり、もっと複雑なアプリケーションの中では頻繁に使われます。

我々はこうしてウィンドウとビューを定義したので、アプリケーションのインプリメンテーション【ファイル】を完了することが出来ます;

// -----------------------------------------------------------------------
// HelloWorldApp.cp
// -----------------------------------------------------------------------
     
     #include "HelloWorldApp.h"
     #include "HelloWindow.h"

     main()
     {
          HelloWorldApp*     myApplication;
          myApplication = new HelloWorldApp();
          myApplication->Run();
          delete myApplication;
          return 0;    
     }


     HelloWorldApp::HelloWorldApp()     : BApplication('HLWD')
     {
          BRect     frameRect;
          frameRect.Set(100,100,280,140);
          HelloWindow*  theWindow = new HelloWindow(frameRect);
     }

我々は#include文をHelloWindowに加え、コンストラクタの中身を書き加えました。 アプリケーションが生成されると、ウィンドウが自動的に生成され、スクリーン上の(100,100,280,140)という位置に配置されます。 アプリケーションは単にウィンドウを生成する必要があるだけです−HelloWindowは、我々が今まで定義した様に、残りの作業をします。

あなたは、我々がアプリケーションメニューの生成や操作について、何も言っていない事に気付いたかもしれません。 そして、我々は「HelloWorldについて」ダイアログボックスをセットアップするためにも、何もしませんでした。 これに対する理由は単純です−それは自動的にあなたのためにBApplicationオブジェクトによって扱われます。 あなたが特別にこうした仕組みを自身のアプリケーション内にオーバーライドしない限り、BApplicationは「<アプリ名>について..」と終了【アイテム】を持つメインメニューを生成し、ユーザが「アバウト」ダイアログを選択した場合、これに対応してBAlertウィンドウを生成します。 これは、ユーザが「終了」を選択したら、アプリケーションはウィンドウを片づけ、終了するのだ、という事も仮定しています。 あなたは、ウィンドウを移動させる事以外には、もはや、メニュー上や「アバウト」ボックス上でマウスイベントを扱う必要は無いのです−こうしたものは、HelloWorldAppの内部で既に生成済みの、BeOSオブジェクトのデフォルトの振る舞いなのです。

ひとまず完成すると、我々のCodeWarriorプロジェクトは下のウィンドウの様に見える筈です。


HelloWorld用に完成したCodeWarriorプロジェクト

次に、我々はプロジェクトをメイク出来ます(プロジェクトメニューのメイク【アイテム】)。 アプリケーションに「HelloWorld」という名前を付けるために、CodeWarrior内で、プロジェクト環境設定を行ったかどうか確認して下さい。これをやっておかないと、アプリケーションは「Application」という名前になってしまいます。この他の役に立つ練習としては、HelloWorldを利用して、これに、おまけとして、ウィンドウ内に「終了」ボタンが表示され、このボタンでウィンドウを閉じ、アプリケーションを終了させられる様に、修正してみて下さい。 これには、単純に、我々がここまでで用いたBViewおよびメッセージングアプローチを利用し、それを異なる種類のインタフェース・オブジェクトに適用するだけです。

この文書では、BeOS環境でのプログラミングに関する概要を紹介しました。 もっと詳しい情報やサンプル・コードについては、Beウェブ・サイト(http://www.be.com)上のDeveloper areatutorial sectionを見て下さい。また、あなたは、BeOSキットと他のオブジェクトに関するより完全な概要を知るために、BeBookという、BeOSのAPI【リファレンス】に目を通したくなるかもしれません。

[ウェブマスターの注: この手引は、我々のマーケティング部長であるMark Gonzalesによって書かれました。 冗談ではありません。]


コピーライト【著作権】©;Be社,1997年 Beは登録商標です。そして、BeOS、BeBox、BeWare、GeekPort、BeロゴとBeOSロゴはBe社の商標です。 文中で述べた全ての他の商標は、それらの所有者の所有物です。
このサイトについてコメントがありますか? webmaster@be.comへ書いて下さい。
ここで使われたアイコンは、Be社の所有物です。 不許複製。


Copyright ©1997 Be, Inc. Be is a registered trademark, and BeOS, BeBox, BeWare, GeekPort, the Be logo and the BeOS logo are trademarks of Be, Inc. All other trademarks mentioned are the property of their respective owners.
Comments about this site? Please write us at webmaster@be.com.
Icons used herein are the property of Be Inc. All rights reserved.


日本語訳:長田 正彦(osada@st.rim.or.jp)
翻訳文中 【○○○】 の形式で記された部分は、訳者のコメントおよび補足です。