DLLでコールバック関数をやりとりする

Delphi-MLに投稿して、回答をもらって解決できました。ありがとうございます。

やりたいこと

  • DLL側にデータを処理する関数/手続きがある
  • DLL側からアクションが開始される(メインアプリのほうではコールバックを登録するだけ)
  • DLL側の関数のポインタがメインアプリのコールバックの引数で与えられる。

コード

library callable;

type
  TWriter = procedure(A, B: Integer); stdcall;
  TCallable = procedure(Writer: TWriter); stdcall;

procedure Writer(A, B: Integer); stdcall;
begin
  WriteLn(A, B);
end;

procedure Call(Callback: TCallable); stdcall;
begin
  Callback(Writer);
end;

exports Call;

begin
end.
program main;

{$APPTYPE CONSOLE}

type
  TWriter = procedure(A, B: Integer); stdcall;
  TCallable = procedure(Writer: TWriter); stdcall;

procedure Call(Callback: TCallable); stdcall; external 'callable';

procedure Callable(Writer: TWriter); stdcall;
begin
  Writer(100, 200);
end;

begin
  Call(Callable);
end.

ポインタ関係の記号 @ や ^ がないのが見やすくていい。
Delphi2009でこのコードをコンパイルしてるけど、多分10年前のDelphiでも問題なく通るんじゃないかと。