Multiplatform Programming Guide/ja
│
Deutsch (de) │
English (en) │
español (es) │
français (fr) │
日本語 (ja) │
polski (pl) │
русский (ru) │
中文(中国大陆) (zh_CN) │
このページは、マルチプラットホーム アプリケーションを書くにあたって考慮すべきチュートリアルの最初のページです。ここでは、これから移植をおこないやすいようなプログラムを書くために、必要な注意事項と、すでに製作したプログラムの移植のプロセスをのべています。この記事をよりよいものにするために、手助けしてくれる他の人を募集しています。
マルチプラットフォームプログラミングへの招待
マルチプラットホーム開発のために、沢山の種類のパソコンが必要でしょうか?
この質問に答えるには、まず、誰が潜在的なユーザーなのか、そして、どのようにプログラムが使われるのかということを決めるべきです。まず、アプリケーションをどういう人々に提供するのか考えてみましょう。
たとえば、ヨーロッパにおいては、デスクトップソフトウエアを開発するなら、WindowsかOS Xで開発することです。OS Xは一番普及しているUnixであり、デスクトップ環境です。 100:10:1の法則はご存知でしょうか。これは、大きな組織やグループのユーザーのことを言っていますが、Windows,Mac,Linuxでも、だいたいにおいてこの比率があてはまると思います。
そのほかの地域では、たとえば、南アメリカでは、Windowsがほとんどですが、Linuxはデスクトッププラットホームでシェアを伸ばしています。商業的にWindowsは大きなスーパーマーケットの販路で売られています。MacOSXはビデオやサウンドの編集に利用されています。
OS XやLinuxを走らせているユーザーのために、開発し、パッケージして配布する「特別な努力」をする甲斐があるでしょうか?プロジェクトが明らかに、クロスプラットホームを必要とするならば、答えは「イエス」でしょう。また、もし「特別な努力」が大変小さなものならば、それもまた「イエス」でしょう。 クロスプラットホームでの開発が、ソフトウエアの王道として、「特別な努力」が終わりのない、あらゆる困難を越えてでも開発するべきである、と考えるなら、その答えも、また「イエス」でしょう。
もし、Webサーバーとしてのソフトウエアを開発する場合は、今のところもっとも利用されているプラットホームはUNIXでしょう。この点において、Linux,Soralis, BSD、そしてほかのUnix互換OSはターゲットとして意味をもつプラットホームです。これに、WindowsNTを加えてもよいでしょう。 (訳注:今なら Windows Serverでしょうか。)
もし、ひとつのプラットフォームについて開発をおこなうならば、そして、将来にわたって他のプラットフォームをサポートしないならば、おそらくFreePascalとLazarusは仕事には最適なツールではないかもしれません。 もし、Windowsのデスクトップのソフトウエアのみを書くならば、Delphiのようがよりよい選択かもしれません。
しかし、一度、クロスプラットフォーム開発をマスターすれば、通常は、ソフトウエアの設計や、問題解決にのみ、注力すればよく、どんなプラットフォームで動作させるかについては、ほとんど楽観的に、自由に考えていれば良いことになります。 つまり、1つのプラットフォームで書いている時と同様、クロスプラットフォーム開発をきちんと身に付けていれば、プラットフォームについての特有な問題はほとんど無視すればいいのです。 しかしながら、いくつかの点で、異なるプラットフォームでプログラムをテストしたり、実際に走らせることは、すべてのターゲットのOSで適用できているかどうか判断する助けになるでしょう。
もし、異なる物理的なPCをそろえるのがいやだったら、デュアルブートのWindows-LinuxのPCや、Mac上の仮想マシンの下で動くWindowsやLinuxを使うとよいでしょう。
Windows と Linux間での相互移植
Windows API 関数
多くのWindowsプログラムは、WindowsAPIを使っています。クロスプラットホームアプリケーションでは、そういうコードは現れません。それは、({$IFDEF Win32}のような)コンパイル条件中に隠されるべきです。
幸いにも、よく使われる多くのWindowsAPI関数はLazarusでのマルチプラットホーム流ではLCLIntfに隠蔽され実装されています。これは、本当にWindowsAPIに多くを依存するプログラムにとって、解決策となるものです。 クロスプラットホームコンポーネントであるLCLを使って置き換えるのがベストです。 たとえば、GDI描画関数は、TCanvasのメンバ関数に置き換えられます。
ファイルシステムの違い
LinuxとWindows間の移植においての基本的な問題のひとつは、ファイルシステムです。 まず、Windowsのファイル名は、大文字小文字を区別しませんが、Unixプラットホームでは区別します。 これは、バグの原因になります。移植性のあるアプリケーションは、両方で成り立つファイル名を付けなくてはなりません。
リナックスには "application directory" はありません
LinuxとWindows間でアプリケーションをポーティングするのに、ひとつよくよく考慮すべきことは、ファイルシステムです。多くのプログラマーは、実行ファイルのパスを得るために、ExtractFilePath(ParamStr(0)) や、 Application.ExeName を使ってきました。そして、プログラムの実行に必要なファイルも、実行ファイルのある位置を基点にしています。これは、Linuxでは正しくない方法です。 ParamStr(0)の文字列は実行ファイルのディレクトリを含まないかもしれないだけでなく、シェルプログラム(sh,bash,など)によって、いろんな違いがあるかもしれません。
Aplication.ExeNameでさえ、実行ファイルがどのディレクトリにあるか知ることができそうですが、それはシンボリックファイルかもしれません。あなたは、リンクのあるディレクトリを取得しているわけです。
それでは、どうしたらよいのでしょうか。Linuxでは、コンフィグレーションやリソースファイルを格納するために、2つの異なった場所を使うべきです。
- リソースファイル. (イメージやヘルプファイル等)
実行ファイルとリソースファイルのために、固定的に許された場所にあり、それは変更されません。 この場所は、 /usr/share/app_name もしくは /opt/app_name のような場所です。
ほとんどのプログラムはroot権限なしで動作させることができます。そして、アプリケーションのために固定された(リソースのための)ディレクトリが与えられ、そのディレクトリは rootユーザーに対しては、書き込み権限がありますが、アプリケーションは、(root権限なしで動作した場合は)このディレクトリに書き込むことができません。リソースファイルからは、読み込みだけが可能です。
- 設定ファイル(コンフィグレーション)
たとえターゲットシステムが異なっていても、設定ファイルに適したファイルの置き場を取得するには、SysUtilsユニットの中のGetAppConfigDir関数を使うことができます。 この関数は、グローバルと呼ばれるひとつのパラメータをとります。もし、これがTrueならば、グローバルな設定ディレクトリが取得できます。グローバルというのは、すなわち、システム上のすべてのユーザーに対しての設定です。 もし、グローバルパラメータがFalseなら、アプリケーションを実行した特定のユーザーに対するディレクトリが返されます。マルチユーザー環境をサポートしないシステムの場合は、これらの2つのディレクトリは同じかもしれません。
アプリケーションの設定のために、 GetAppConfigFileというファイルもあります。
異なったシステム上で、これらの出力のサンプルを見てみましょう。
program project1; {$mode objfpc}{$H+} uses SysUtils; begin WriteLn(GetAppConfigDir(True)); WriteLn(GetAppConfigDir(False)); WriteLn(GetAppConfigFile(True)); WriteLn(GetAppConfigFile(False)); end.
GNU/Linux システムの場合は次のように出力されます。
/etc /home/felipe/project1 /etc/project1.cfg /home/felipe/.project1
グローバルな設定ファイルは /etcディレクトリにあり、ローカルな設定ファイルはユーザーのホームディレクトリに隠しフォルダとして保存されます。Linuxでは、ドット(.)ではじまるディレクトリは隠しフォルダです。 GetAppConfigDirで返される場所にディレクトリを作り、コンフィグレーションファイル類をそこへ入れることもできます。
Windows XP の場合は次のように出力されます。
C:\Programas\teste C:\Documents and Settings\felipe\Configurações Locais\Dados de aplicativos\project2 C:\Programas\teste\project2.cfg C:\Documents and Settings\felipe\Configurações Locais\Dados de aplicativos\project2\project2.cfg
Windowsでは、関数は、グローバルな設定のために、アプリケーションが入れられているディレクトリを返すことに注意しましょう。
UPX Note: The use of UPX interferes with the use of the GetAppConfigDir and GetAppConfigFile functions.
WindowsのCOMオートメーションを使わず、それっぽい事をやるには
Windowsにおいて、オートメーションは、他のプログラムをリモート操作したり、他のプログラムから操作させたりするのに、強力な方法です。 Delphiでは、オートメーションクライアント、オートメーションサーバーのどちらも作成することができます。これは、他のプログラムを操作したり、他のプログラムから操作されるプログラムのことです。
オートメーションは、OS Xや Linuxでは利用できません。しかし、OS XではAppleScriptを使って同じようなことはできます。
AppleScriptはオートメーションと、ある面はとても似ています。たとえば、他のプログラムを操作するスクリプトを書くことができます。これは、AppleScriptがNeoOffice(OpenOffice.orgのMac版)を開始する とても簡単な例です。
tell application "NeoOffice" launch end tell
AppleScriptから操作されるように設計されているアプリケーションは、アプリケーションを使うためのクラスとコマンドの"辞書"を持っています。それは、Windowsのオートメーションサーバーと似ています。
しかしながら、NeoOfficeのような辞書をもっていないアプリケーションでさえ、"launch","activate","quit"といったコマンドに応答することができます。
AppleScriptはOS Xスクリプトエディタや、ファインダー、ドックにドロップできるどのようなアプリケーションからでも実行できます。
次の例のように、自分のプログラムからAppleSriptを実行することもできます。
Shell('myscript.applescript');
これはスクリプトが明示されているファイルにあることを仮定しています。スクリプトをアプリケーションから、OS X OsaScriptコマンドを使ってすぐに走らせる事もできます。
Shell('osascript -e '#39'tell application "NeoOffice"'#39 + ' -e '#39'launch'#39' -e '#39'end tell'#39); {Note use of #39 to single-quote the parameters}
しかし、これらの例は、次のようなopenコマンドと同等です。
Shell('open -a NeoOffice');
AppleScriptの真の力はリモートからプログラムを操作して、文書を開いたり作成したり、ほかの機能を使って自動化できることです。 どれくらいプログラムに対して操作できるか、というのは、どれくらいAppleScript辞書に拡張されているか、ということと同じです。たとえば、マイクロソフトOffice XプログラムはAppleScriptではあまり使えるものではありませんでした。しかし、新しいOfiice 2004プログラムは完全にAppleScript向けに書き直され、WindowsのOfficeのオートメーションサーバー機能と同等になっています。
一方、Linuxのシェルは洗練されたコマンドラインスクリプトをサポートしています。スクリプトの方法はプログラムにどんなコマンドラインを渡せるか、ということで決まっています。Windowsのオートメーションサーバーや、OS XのAppleScriptのように、プログラムの内部のクラスやコマンドはLinuxでは利用できません。
Windowsのように、多くのOS XやLinuxのプログラムは複数のライブラリファイルから成り立っています。 (たとえば、.dylibや .so のような。)一部、これらのライブラリはあなたが書くプログラムでも使えるように設計されています。 これは、あなたのプログラムに、外部的な機能を付け加えることはできますが、外部プログラムそのものを操作するものとは、完全に同じではありません。しかしながら、あなたのプログラムは外部のプログラムのライブラリをリンクして使うことができれば、ほかのプログラム用のライブラリのように使うことができます。
(訳注:WindowsのCOMのオートメーションサーバようなことをするには、Linuxでシェアードオブジェクトのようなライブラリが共有され、ユーザーに開放ているプログラムで、リンクできれば、似たことは可能であるということです。)
付記
- http://www.midnightbeach.com/jon/pubs/Kylix.html A guide for Windows programmers starting with Kylix. Many of concepts / code snippets apply to Lazarus.