特集

.NET完全対応で生まれ変わったDelphi 8

泉 祐介
2004/06/26

Page1 Page2 Page3 Page4

VCLを.NET環境に移植した「VCL for .NET」

 Delphi 7までのVCLはWin32プラットフォーム上で動作するアプリケーションのためのライブラリであり、その基底にはWin32 APIが存在した。そのVCLを利用したアプリケーションが、Delphi 8では.NET Framework上で動作するわけだが、これを可能にしたのが「VCL for .NET」と呼ばれるライブラリである。なお、本稿でここまで解説してきたVCLフォームにおける「VCL」とは、実際にはこのVCL for .NETのことなので注意してほしい。

 VCL for .NETは、その名のとおりVCLを.NET Framework上に移植したものである。ちなみに、従来のWin32プラットフォーム用のVCLは、VCL for .NETと区別するために「VCL for Win32」と呼ばれる。

VCL for .NETとそのアプリケーション
VCL for .NETは、従来のWin32プラットフォーム用のVCLである「VCL for Win32」を.NET Framework上に移植したもの。ただしその内部では、.NET Frameworkのプラットフォーム呼び出し機能を通じてWin32 APIを使用する。

 これらVCL for Win32とVCL for .NETは相互に互換性があるため、理屈のうえではVCL for Win32を使用するWin32アプリケーションと、VCL for .NETを使用する.NETアプリケーションとの間でコードの共有が可能である(詳しくは後述のコラムを参照)。

 ただし、.NETの(安全な)マネージ・コードではポインタが使用できないため、従来はポインタ型をとっていたパラメータや戻り値、プロパティなどはその型が変更されている(詳細は下表を参照)。コードを共有する場合にはこの点に十分に注意する必要があるだろう。

変更された型 VCL for .NETでの変更内容
型なしポインタ(Pointer型) ・ほとんどはTObject型に置き換え
・コンテキストによって型が変わるパラメータとして用いられていた型なしポインタは、ルーチン(手続き/関数)をオーバーロードして、可能性のあるコンテキストごとに、コンテキストに合った型を持つルーチンを用意
・アンマネージ・コード(Win32 APIなど)の呼び出しでは、.NET FrameworkのIntPtr型(System名前空間)に置き換え
C言語スタイルの文字列(PChar型) ・String型に置き換え
・アンマネージ・コード(Win32 APIなど)の呼び出しでは一部を.NET FrameworkのStringBuilder型(System.Text名前空間)に置き換え
・PChar型の文字列を操作するルーチンはライブラリから削除
手続きポインタ/関数ポインタ ・.NETのデリゲートに置き換え
ポインタの排除に伴ったVCL for .NETにおける「型」の変更点
.NETのマネージ・コードではポインタを使用しないため、従来はポインタ型をとっていたパラメータや戻り値、プロパティなどはその型が変更されている。コードを共有する場合にはこの点に十分に注意する必要があるだろう。

 .NETではクラスは何らかの名前空間に含まれるのが一般的である。VCL for .NETのクラスも例外ではなく、ほとんどのクラスは「Borland.Vcl」で始まる名前空間に含まれる。

 具体的には、Borland.Vclの後ろにVCL for Win32におけるそのクラスのユニット名をつなげた名前空間となる(一部の例外はあるが)。例えばTFormクラスは、VCL for Win32ではFormsユニットに含まれていたが、VCL for .NETではBorland.Vcl.Forms名前空間に含まれるといった具合である。なお、Systemユニットだけは、対応する名前空間がBorland.Delphi.Systemになっている。

 ところで、VCL for .NETのライブラリ・ファイルには、.NETのアセンブリ(DLLファイル)として提供されるランタイム・ライブラリと、中間ファイル*の形式で提供されるスタティック・ライブラリの2種類がある。スタティック・ライブラリは端的にいえばライブラリの内容(の一部)をアプリケーション本体に含めるためのものである。

* Delphi 8の中間ファイルには.dcuilという拡張子が付く。Delphi 7までは.dcuという拡張子で、DCUはDelphi Compiled Unit(Delphiコンパイル済みユニット)の略。恐らく、DCUILはMSILで記述されたコンパイル済みユニットという意味だろう。

 従って、スタティック・ライブラリを使用すればVCL for .NETのランタイム・ライブラリを配布する手間が省ける。ただし、スタティック・ライブラリを使用すると実行ファイルが肥大化するので(前述の画像表示プログラムだと1.3Mbytes超になる。ちなみにランタイム・ライブラリのときは9Kbytes程度)、実際には場面に応じて使い分ける必要があるだろう。Delphi 8ではライブラリ・ファイルごとにランタイム・ライブラリとスタティック・ライブラリを選択できる。

 なお、VCL for .NETは確かに.NET Framework上で動作するのだが、正しくは「Win32プラットフォームの.NET Framework」上でしか動作しない。これはVCL for .NETに含まれるコンポーネントの多くが内部でWin32 APIを呼び出しているためだ。

 従って、「.NET Compact Framework」上で動作するアプリケーションを作成する場合はVCLではなく(後述の)Windowsフォームを利用して作成する必要がある。なお、実際にはWindowsフォームのコンポーネントも最終的にはWin32 APIを呼び出すが、それはあくまでもWin32プラットフォーム上での話である。モバイル環境を対象とした.NET Compact Frameworkでは、Win32 APIではなく、そのサブセットであるWindows CE用のAPIを呼び出している。

 余談になるが、VCL for .NETのソース・コードはDelphi 8に同梱されている。

過去のバージョンとの互換性

 過去のバージョンとの互換性は、過去の資産を活用するうえでは非常に重要なポイントとなるため、気にしている読者も多いことだろう。特に、Delphi 8では.NET Framework対応ということもあり、Visual Basic(以下VB)からVB.NETに移植するときのような非常に大掛かりな作業が必要になるのでは、と心配する読者もいるかもしれない。

 きちんと検証したわけではないが、前述したようにVCL for Win32とVCL for .NETの間でソース・コードを共有できることから、筆者はDelphi 8への対応に膨大な作業が必要になることはそれほど多くないと考えている。

 そもそも、VBからVB.NETへの移植を困難にしているのは、両者の間で大幅な言語仕様の変更があったこと、そしてVBの標準コントロールが廃止され、代わりにWindowsフォーム(.NET Framework)のコントロールを使用するようになったことである。

 もちろん、Delphiでも言語仕様は変更されているが(後述)、VB.NETのように大幅に変更されたわけではない。また、コンポーネントの互換性はVCL for .NETにより保証されている(つまり、ほぼすべてのVCLコンポーネントがVCL for .NETで利用可能だ)。

 ただし、1つだけ必ず注意しなければならない点がある。それは、上記のVCL for .NETの解説中でも述べたことだが、.NET Frameworkではポインタが(事実上)使用不可能なことである。そのため、とにかくコードからポインタを排除しなければならない*。従って、特にポインタを多用しているようなコードでは、ポインタを排除するために多くの作業をしなければならないかもしれない。

* 実は、.NET Frameworkでもポインタがまったく使用不可能というわけではない。実際、Delphi 8でも「安全でないコード」であることをコンパイラに通知すればポインタが使用可能だ。ポインタを使用したコードは、.NET Frameworkによってメモリ管理されない「安全でない」コードとなる。この安全でないコードは、ローカル環境以外では(より正確には、.NET Frameworkのコード・アクセス・セキュリティで完全な信頼(FullTrust)が設定されている場合、あるいは「セキュリティ」アクセス許可の中の「評価をスキップする」許可が設定されていない場合)、セキュリティ例外が発生して実行できないので、可能な限り回避すべきである。それに、ポインタを使用するにしてもVCL for .NETにおける仕様変更には対応しなければならない。

 もう1つ問題となり得るのが、サード・パーティ製のコンポーネントの利用である。

 Delphiでは数多くのコンポーネントがインターネットなどを通じて配布されており、「Delphian World」のようにコンポーネントを専門に配布するサイトも存在する。これらのコンポーネントは有料/無料を問わず、バイナリ・ファイル(DCU形式)のみが提供され、ソース・ファイルが同梱されていないことも多い。

 しかし、Delphi 8では.NET対応に伴ってバイナリ・ファイルの形式が変更されているため、それらのコンポーネントを利用するのは残念ながら不可能だと思われる。もちろん、ソース・ファイルが同梱されているコンポーネントならば、バイナリ・ファイルのリビルドを試してみる価値はあるだろう。とはいえ、サード・パーティ製のコンポーネントは特定のDelphiのバージョンに依存することが少なくないので(必ずしもコンポーネントの作者に原因があるわけではないようだが)、過大な期待はしない方がよいかもしれない。

 なお、ボーランドのサイトにある次のページには、Win32から.NET Frameworkへの移行に関してより具体的な情報が記載されているので参考にするとよいだろう。

Borland Delphi 8を使用したBorland Delphi Win32アプリケーションのMicrosoft .NET Frameworkへの移行(PDF)

 また、Delphi 8に付属のヘルプ・ファイルにも、修正の必要があるコードに関する説明がなされているページが存在するので、そちらも参照するとよい。

【コラム】
Delphi 7とDelphi 8におけるファイルの互換性

 VCL for Win32とVCL for .NETでコードの共有が可能と前述したが、実際に共有するにはファイル形式の互換性が問題となる。

 
筆者が試した範囲では、Delphi 8で保存したプロジェクトやフォーム・ファイル、ユニット・ファイルをDelphi 7で読み込もうとすると、フォームが表示されない、ビルドが通らないなどの問題が生じた。このような問題が生じる理由としては、

  • Delphi 8ではuses節に.NET Frameworkの名前空間も記述されるようになった。また、ユニット・ファイルの保存時に、ユニット名ではなくBorland.Vclで始まる名前空間がuses節に補完されるようになった*。いずれにせよDelphi 7では存在しないユニット名であると認識してしまい、これが原因でビルドに失敗する(なお、Delphi 8におけるuses節の扱いについては後述する)。
  • Delphi 8ではDelphiフォーム・ファイルの拡張子が.dfmから.nfmに変更された。Delphi 7ではこの拡張子.nfmのファイルをDelphiフォーム・ファイルであると認識しないため、フォームが表示されない。

といった点が考えられる。

* Delphi言語では、別のユニットで宣言されているクラスを使用するときには、そのユニット名をuses節に記述する必要がある。ただしIDEでコードを編集している場合は、ファイルを保存する際にIDEによって必要なユニット名が補完される。

 逆に、Delphi 7で保存したファイルをDelphi 8で読み込む場合に関しては、目立った問題が生じることなくファイルを読み込むことができ、プロジェクトのビルドも正常に行われる。

 従って、VCL for Win32とVCL for .NETでコードを共有する場合は、主にDelphi 7でフォームをデザインすることになるだろう。

 なお、前出のボーランドのページ「Borland Delphi 8を使用したBorland Delphi Win32アプリケーションのMicrosoft .NET Frameworkへの移行」には、コードを共有するためのヒントも記載されている。

 ここまでVCLを中心に見てきたが、前述したようにDelphi 8ではWindowsフォーム・アプリケーションの開発も可能である。次に、DelphiによるWindowsフォーム・アプリケーションの開発を紹介しよう。


 INDEX
  [特集].NET完全対応で生まれ変わったDelphi 8
     1..NET完全対応のDelphi 8
     2.VCLフォーム・アプリケーションの開発
   3.VCLを.NET環境に移植した「VCL for .NET」
     4.Windowsフォーム・アプリケーションの開発
 


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間