Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2022年09月01日] [更新 2022年09月01日] Delphi 一般・その他
Lazarus で DLL を作成
動作確認等 Windows 10 ビルド 19043 Pro 64 bit + lazarus-2.0.12 32 bit
[整理番号 - 1530]







Lazarus で DLL を作成


Lazarus で、DLL を新規に作成する手順と、簡単なサンプル作成の記事です。



[備考]
Lazarus で 作成した DLL は、他のプログラミング言語でも利用できますが、C# など、.NET 用言語では特別な処理が必要です。
64 ビット版の Lazarus で作成した DLL は、32 ビットの EXE では使用できません。32 ビット版の Lazarus で作成した DLL は、64 ビットの EXE てば使用できません。




01_DLL を新規作成


IDE のメニューの [プロジェクト] から [新規プロジェクト] を選択します。下図のダイアログが起動します。このダイアログの左ペインの [ライブラリ] をダブルクリックするか、選択して [OK] ボタンで閉じると、新規の DLL 作成の状態になります。



図1
DLL の新規作成
  • [ライブラリ] を選択
  • [OK] をクリック

プロジェクトのコードを以下のようにします。
この DLL は、整数の加算と実数の乗算の関数だけを実装しています。

stdcall は、関数類の引数などの内部処理の、Pascal における呼び出し規約です。Windows API でもデファクトスタンダードの呼出規約となっています。DLL 内の関数を使用する際の一種の「おまじない」ぐらいに考えても差支えありません。
exports には、外部から使用可能な関数名を列挙します。ここに列挙した関数や手続きだけが外部から利用できます。



リスト1
library SampleDLL;

{$mode objfpc}{$H+}

uses
  Classes;

function AddValue(Val1, Val2: Integer): Integer; stdcall;
begin
  Result := Val1 + Val2;
end;

function MulValue(Val1, Val2: Double): Double; stdcall;
begin
  Result := Val1 * Val2;
end;

exports
  AddValue,
  MulValue;

begin
end.


[プロジェクト] [名前を付けてプロジェクトを保存] で、SampleDLL.lpr という名前で、任意のフォルダに保存します。
保存したら [Ctrl] + [F9] でコンパイルしてIDE を閉じます。
下図は、保存されたファイルの一覧です。



図2
保存してコンパイルした結果
  • DLL が作成されている
  • SampleDLL.lpr がプロジェクトファイル




02_DLL を使用するプログラムを作成して実行


Lazarus の IDE を起動したら、[プロジェクト] [新規プロジェクト] を選択します。前項と同じダイアログが起動します。左ペインから [アプリケーション] を選択します。
この操作は、プロジェクトの新規作成状態で Lazarus が起動している場合は必要ありません。 

フォームに TButton を 2 つ配置して、Unit1 のコードを、図の下のコードにします。Windows API の関数を使用すために、uses に LazUTF8, Windows を追加しています。DLL 内の関数を他のユニットで使用する必要がなければ、関数の宣言を implementation 部に記述しても構いません。
external 指令は、この関数を外部から呼び込むことを意味しています。その後の文字列が、その関数が存在する DLL の名前です。

このプロジェクトを、[プロジェクト] [名前を付けてプロジェクトを保存] で、DLL のプロジェクトファイルと同じフォルダ内に保存します。保存したら [F9] でコンパイルして実行します。
下図が実行結果です。



図3
[Button1] クリック
  • DLL 内の関数 AddValue を実行
図4
[Button2] クリック
  • DLL 内の関数 MulValue を実行

リスト2
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  LazUTF8, Windows;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private

  public

  end;

function AddValue(AVal1, AVal2: Integer): Integer; stdcall; external 'SampleDLL.dll';
function MulValue(AVal1, AVal2: Double): Double; stdcall; external 'SampleDLL.dll';

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  LValue : Integer;
  LText  : string;
  LCap   : string;
begin
  LValue := AddValue(3000, 500);

  LText := UTF8ToWinCP('計算結果' + sLineBreak + FormatFloat(',0', LValue));
  LCap  := UTF8ToWinCP('情報');
  MessageBox(Handle, PChar(LText), PChar(LCap), MB_ICONINFORMATION);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  LValue : Double;
  LText  : string;
  LCap   : string;
begin
  LValue := MulValue(3000, 500);

  LText := UTF8ToWinCP('計算結果' + sLineBreak + FormatFloat(',0.000', LValue));
  LCap  := UTF8ToWinCP('情報');
  MessageBox(Handle, PChar(LText), PChar(LCap), MB_ICONINFORMATION);
end;

end.