言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

Pascal辞典

  1. トップページ
  2. Pascal辞典
  3. Delphi と Free Pascal(FPC)

Delphi と Free Pascal(FPC)

『Pascal』の商用ラインを代表する Delphi と、オープンソースラインを代表する Free Pascal(FPC) は、どちらも Turbo Pascal の遺産を継承しながら独自の方向へと発展してきました。Delphi は Borland(現 Embarcadero)が Windows 向け RAD ツールとして商業的に発展させ、Free Pascal はコミュニティ主導でマルチプラットフォーム・オープンソースの方向へと進化しました。このページでは両者の特徴・相違点・共通点を整理します。

Delphi の概要

項目内容
開発元Borland → CodeGear → Embarcadero Technologies と引き継がれています。現在は Embarcadero 社が開発・販売しています。
初版リリース1995年。Turbo Pascal の後継として Windows 向け RAD(Rapid Application Development)ツールを目指してリリースされました。
言語Object Pascal(Delphi 方言)を採用しています。クラス・インターフェース・ジェネリクス・匿名メソッドなど現代的な機能を順次追加してきました。
GUI フレームワークVCL(Visual Component Library)を Windows 向けに、FMX(FireMonkey)を Windows・macOS・iOS・Android 向けのクロスプラットフォームフレームワークとして提供しています。
対応プラットフォームWindows・macOS・iOS・Android・Linux(サーバー用途限定)に対応しています。
ライセンス商用ライセンスです。Community Edition として個人・学習・オープンソース開発向けに無償版も提供されています。
主な用途エンタープライズ向け Windows アプリケーション・業務システム・データベースフロントエンドの開発で多く使われています。

Free Pascal(FPC)の概要

項目内容
開発元Florian Klämpfl を中心とするオープンソースコミュニティが開発しています。
初版リリース1993年ごろに開発が始まり、1996年に公開されました。Turbo Pascal 7.0 および Delphi との高い互換性を目標としています。
言語Turbo Pascal モード・Delphi モード・Free Pascal 独自モードなど複数のコンパイルモードを持ちます。スイッチ {$mode delphi} などで切り替えられます。
GUI フレームワーク単体では GUI を持たず、Lazarus IDE と組み合わせることで LCL(Lazarus Component Library)を使ったクロスプラットフォーム GUI 開発が可能になります。
対応プラットフォームWindows・macOS・Linux・FreeBSD・Raspberry Pi(ARM)・Nintendo Switch など非常に多くのプラットフォームに対応しています。
ライセンスGPL(コンパイラ本体)および LGPL with linking exception(ランタイムライブラリ)です。商用ソフトウェアにも組み込んで利用できます。
主な用途クロスプラットフォームのコマンドラインツール・組み込みシステム・Lazarus を使ったデスクトップアプリケーション・プログラミング教育に使われています。

Delphi と Free Pascal の比較

比較項目DelphiFree Pascal(FPC)
ライセンス商用(Community Edition あり)です。オープンソース(GPL/LGPL)です。
言語仕様の拡張Embarcadero が主導して追加・決定します。コミュニティが合意して追加・決定します。
Delphi 互換性Delphi 自身が基準です。{$mode delphi} で高い互換性を持ちます。
IDERAD Studio(統合 IDE(Integrated Development Environment、統合開発環境))が付属します。Lazarus IDE を別途インストールして使います。
対応 CPU アーキテクチャx86・x86_64・ARM・ARM64 などに対応します。x86・x86_64・ARM・MIPS・RISC-V など非常に多くに対応します。
コミュニティ規模商用サポートと有償ドキュメントが充実しています。フォーラム・Wiki・GitHub などで無償のリソースが豊富です。
ランタイムライブラリRTL(Run-Time Library、ランタイムライブラリ)・VCL・FMX などが提供されます。RTL・FCL(Free Component Library、フリーコンポーネントライブラリ)が提供されます。

コンパイルモードの切り替え(Free Pascal)

モード指定概要
{$mode fpc}Free Pascal 独自の既定モードです。Turbo Pascal より厳格な型チェックが行われます。
{$mode tp}Turbo Pascal 7.0 互換モードです。古いソースコードを再利用する際に使います。
{$mode delphi}Delphi 互換モードです。Delphi で書かれたソースを Free Pascal でコンパイルする際に使います。
{$mode objfpc}Free Pascal 独自のオブジェクト指向拡張モードです。Delphi との互換性を保ちつつ FPC 独自機能を追加しています。

サンプルコード

jujutsu_delphi_fpc.pas
{ jujutsu_delphi_fpc.pas — Delphi / Free Pascal の機能比較サンプルです }
{ 呪術廻戦のキャラクターデータを使って }
{ クラス・インターフェース・例外処理など }
{ Delphi と Free Pascal の両方で動作する Object Pascal の書き方を確認します }
{
  コンパイルと実行:
    fpc jujutsu_delphi_fpc.pas && ./jujutsu_delphi_fpc
}

{$mode delphi}  { Free Pascal で Delphi 互換モードを有効にします }

program jujutsu_delphi_fpc;

uses
  SysUtils;  { IntToStr・FloatToStrF などを使います }

{ ============================================================
  インターフェース宣言
  Delphi・Free Pascal(objfpc/delphi モード)両方でサポートされます
  ============================================================ }
type
  ISorcerer = interface
    ['{A1B2C3D4-0000-0000-0000-000000000001}']  { GUID(Globally Unique Identifier、グローバル一意識別子)— Delphi 互換 }
    function  GetName      : string;
    function  GetGrade     : integer;
    procedure ShowInfo;
  end;

{ ============================================================
  基底クラス TSorcerer
  ============================================================ }
  TSorcerer = class(TInterfacedObject, ISorcerer)
  private
    FName  : string;   { 術師の名前 }
    FGrade : integer;  { 等級(1 が最上位) }
  public
    constructor Create(const AName : string; const AGrade : integer);
    function  GetName  : string;   virtual;
    function  GetGrade : integer;  virtual;
    procedure ShowInfo;            virtual;
  end;

{ ============================================================
  派生クラス TSpecialGradeSorcerer(特級呪術師)
  ============================================================ }
  TSpecialGradeSorcerer = class(TSorcerer)
  private
    FDomain : string;  { 領域展開の名称 }
  public
    constructor Create(const AName : string; const ADomain : string);
    procedure ShowInfo;  override;  { ShowInfo をオーバーライドします }
  end;

{ ============================================================
  TSorcerer の実装
  ============================================================ }
constructor TSorcerer.Create(const AName : string; const AGrade : integer);
begin
  inherited Create;
  FName  := AName;
  FGrade := AGrade;
end;

function TSorcerer.GetName : string;
begin
  Result := FName;
end;

function TSorcerer.GetGrade : integer;
begin
  Result := FGrade;
end;

procedure TSorcerer.ShowInfo;
begin
  WriteLn('  名前: ', FName, '  等級: ', IntToStr(FGrade), '級');
end;

{ ============================================================
  TSpecialGradeSorcerer の実装
  ============================================================ }
constructor TSpecialGradeSorcerer.Create(const AName : string; const ADomain : string);
begin
  inherited Create(AName, 0);  { 等級 0 = 特級 }
  FDomain := ADomain;
end;

procedure TSpecialGradeSorcerer.ShowInfo;
begin
  WriteLn('  名前: ', GetName, '  等級: 特級  領域展開: ', FDomain);
end;

{ ============================================================
  メインプログラム
  ============================================================ }
var
  { 呪術廻戦キャラクターのオブジェクト配列 }
  sorcerers : array[1..5] of TSorcerer;
  i         : integer;

begin
  { -----------------------------------------------
    呪術師オブジェクトの生成
    特級呪術師は TSpecialGradeSorcerer で生成します
    ----------------------------------------------- }
  sorcerers[1] := TSpecialGradeSorcerer.Create('五条悟',   '無量空処');
  sorcerers[2] := TSpecialGradeSorcerer.Create('夏油傑',   '偽夏油の術式');
  sorcerers[3] := TSorcerer.Create('虎杖悠仁', 1);
  sorcerers[4] := TSorcerer.Create('伏黒恵',   2);
  sorcerers[5] := TSorcerer.Create('釘崎野薔薇', 3);

  { -----------------------------------------------
    全術師の情報を表示します
    ----------------------------------------------- }
  WriteLn('===== 呪術師名簿 =====');
  for i := 1 to 5 do begin
    sorcerers[i].ShowInfo;
  end;
  WriteLn('');

  { -----------------------------------------------
    例外処理のサンプル
    Free Pascal・Delphi 両方で同じ構文を使えます
    ----------------------------------------------- }
  WriteLn('===== 等級チェック(例外処理) =====');
  try
    { 等級が範囲外の場合に例外を発生させます }
    if sorcerers[1].GetGrade <= 0 then
      raise ERangeError.Create('特級は等級 0 以下です(特別扱いが必要)。');
  except
    on E : ERangeError do
      WriteLn('  [キャッチ] ERangeError: ', E.Message);
    on E : Exception do
      WriteLn('  [キャッチ] Exception: ', E.Message);
  end;
  WriteLn('');

  { -----------------------------------------------
    インターフェース経由でのアクセス
    ISorcerer インターフェース変数に代入します
    ----------------------------------------------- }
  WriteLn('===== インターフェース経由で名前を取得 =====');
  for i := 1 to 5 do begin
    WriteLn('  ISorcerer.GetName -> ', (sorcerers[i] as ISorcerer).GetName);
  end;
  WriteLn('');

  WriteLn('処理が完了しました。');
end.
fpc jujutsu_delphi_fpc.pas && ./jujutsu_delphi_fpc
Free Pascal Compiler version 3.2.2 ...
Linking ./jujutsu_delphi_fpc
===== 呪術師名簿 =====
  名前: 五条悟  等級: 特級  領域展開: 無量空処
  名前: 夏油傑  等級: 特級  領域展開: 偽夏油の術式
  名前: 虎杖悠仁  等級: 1級
  名前: 伏黒恵  等級: 2級
  名前: 釘崎野薔薇  等級: 3級

===== 等級チェック(例外処理) =====
  [キャッチ] ERangeError: 特級は等級 0 以下です(特別扱いが必要)。

===== インターフェース経由で名前を取得 =====
  ISorcerer.GetName -> 五条悟
  ISorcerer.GetName -> 夏油傑
  ISorcerer.GetName -> 虎杖悠仁
  ISorcerer.GetName -> 伏黒恵
  ISorcerer.GetName -> 釘崎野薔薇

処理が完了しました。
jujutsu_ifdef.pas
{$mode delphi}

program jujutsu_ifdef;

uses
  SysUtils;

var
  platform_name : string;
  char_name     : string;

begin
  char_name := '五条悟';

  { {$IFDEF} による条件コンパイル: プラットフォームで処理を分岐します }
  {$IFDEF WINDOWS}
    platform_name := 'Windows';
  {$ELSE}
    {$IFDEF LINUX}
      platform_name := 'Linux';
    {$ELSE}
      platform_name := '不明なプラットフォーム';
    {$ENDIF}
  {$ENDIF}

  WriteLn(char_name, ' が ', platform_name, ' 上で起動しました。');
  WriteLn('Free Pascal / Delphi どちらでもコンパイル可能です。');
end.
fpc jujutsu_ifdef.pas && ./jujutsu_ifdef
Free Pascal Compiler version ...
Linking ./jujutsu_ifdef
五条悟 が Linux 上で起動しました。
Free Pascal / Delphi どちらでもコンパイル可能です。
jujutsu_unit_diff.pas
{$mode delphi}

program jujutsu_unit_diff;

uses
  SysUtils,
  {$IFDEF WINDOWS}
    Windows      { Windows API を使う場合は Windows ユニットを uses します }
  {$ELSE}
    BaseUnix     { Linux/macOS では BaseUnix ユニットを uses します }
  {$ENDIF}
  ;

var
  char_name : string;
  pid       : LongInt;

begin
  char_name := '虎杖悠仁';

  { プロセス ID の取得方法もプラットフォームで異なります }
  {$IFDEF WINDOWS}
    pid := GetCurrentProcessId;
  {$ELSE}
    pid := fpGetPid;
  {$ENDIF}

  WriteLn(char_name, ' のプロセス ID: ', pid);
  WriteLn('ユニット名はプラットフォームごとに異なります。');
end.
fpc jujutsu_unit_diff.pas && ./jujutsu_unit_diff
Free Pascal Compiler version ...
Linking ./jujutsu_unit_diff
虎杖悠仁 のプロセス ID: 12345
ユニット名はプラットフォームごとに異なります。

よくあるミス

Delphi専用構文をFPCで{$mode delphi}なしで使用する

FPC のデフォルトモードは ObjFPC で、Delphi とは構文が異なる部分があります。Delphi の構文をそのまま使うには {$mode delphi} をファイル先頭に付けます。付けないと「identifier not found」や型不一致のコンパイルエラーが出ることがあります。

{ Delphi 構文を FPC で使う場合は先頭に記述します }
{$mode delphi}

program sample;

uses
  SysUtils;

begin
  WriteLn('Delphi 互換モードで動作しています。');
end.

インターフェースのGUIDを書き忘れる

Delphi のインターフェースには GUID(['{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'])が必要なケースがあります。GUID なしだと QueryInterface が正しく機能せず、インターフェース型キャスト(as 演算子)が実行時エラーになります。

type
  { GUID なし: QueryInterface が機能しません }
  INoGuid = interface
    procedure DoSomething;
  end;

  { GUID あり: as 演算子でのキャストが機能します }
  IWithGuid = interface
    ['{A1B2C3D4-1234-5678-ABCD-000000000001}']
    procedure DoSomething;
  end;

概要

Delphi は商用の完成度の高い IDE・フレームワーク・サポートを求める場合に、Free Pascal(FPC) はオープンソース・クロスプラットフォーム・コスト無しで始めたい場合に適しています。両者は Object Pascal という共通の言語基盤を持っており、{$mode delphi} ディレクティブを使うことで Free Pascal 上でも多くの Delphi コードをそのままコンパイルできます。クラス・インターフェース・例外処理など Object Pascal の機能については クラスの基本インターフェース型例外処理 も合わせて参照してください。Free Pascal のセットアップ方法は Free Pascal のセットアップ を確認してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。