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.