5

フォームを開いてレポートを印刷するプロシージャを dll に作成しました。この手順は、exe から完全に機能します。このプロシージャとフォームを含むユニットを dll にラップし、プロシージャを次のようにエクスポートしました。

{$R *.res}


Procedure PrintTopSellers; stdcall;
begin
  Form1 := TForm1.create(nil);
  GetMonth := TGetMonth.create(nil);
  Form1.PrintTopSellers;
end;


exports PrintTopSellers;

begin
end.

ここで、次のように exe からこのプロシージャ PrintTopSellers を呼び出します。

procedure TForm1.Button5Click(Sender: TObject);
type
  TRead_iButton = function :integer;
var
    DLL_Handle: THandle;
    Read_iButton: TRead_iButton;
Begin
    DLL_Handle := LoadLibrary('c:\Catalog.dll');
    if DLL_Handle <> 0 then
    begin
       @Read_iButton:= GetProcAddress(DLL_Handle, 'PrintTopSellers');
        Read_iButton;
    end;
    application.ProcessMessages;
    FreeLibrary(DLL_Handle);

end;

プロシージャの呼び出しは完全に機能します。しかし、呼び出し元の exe を閉じると、アクセス違反が発生します - 「アドレス 00BAC89C でアクセス違反。アドレス 00BAC89C の読み取り」。

任意の支援に感謝します。Delphi 7を使用しています。ありがとう

4

2 に答える 2

6

Form1DLL で、ウィンドウ コントロールを作成しています。しかし、あなたはそれを決して破壊しません。次に、DLL によって作成されたすべてのウィンドウのウィンドウ プロシージャを実装するコードをアンロードする DLL をアンロードします。おそらくプロセスがシャットダウンすると、ウィンドウ プロシージャが呼び出されますが、コードはもうありません。

DLL が作成するすべてのオブジェクトを破棄して、問題を修正します。最善のアプローチは、PrintTopSellers終了時にそれを行うことです。

Procedure PrintTopSellers; stdcall;
begin
  Form1 := TForm1.create(nil);
  try
    GetMonth := TGetMonth.create(nil);
    try
      Form1.PrintTopSellers;
    finally
      GetMonth.Free;
    end;
  finally
    Form1.Free;
  end;
end;

DLL をロードするコードで、TRead_iButtonが正しく宣言されていません。そのはず

TRead_iButton = procedure; stdcall;

しかし、署名の不一致はパラメーターなしのプロシージャーにとって問題がないため、実際にはここで問題を説明することはできません。

于 2012-09-20T10:42:57.057 に答える
3

「TRead_iButton = 関数: 整数; レジスタ;」

"プロシージャ PrintTopSellers; stdcall;"

絶対に異なる慣習/タイプですね。

それらを同じにします。そして、DLLを捨ててパッケージ(BPL)を使用すると、コンパイラはそのようなエラーから安全になります


また、Form1.PrintTopSellers にも TGetMonth にもコードはありません。すべてが、DLL がアンロードされた後にアクセスを取得する、ホスト exe 内にダングリング ポインターを残す可能性があります。


AV につながる一連の関数呼び出しを正確に表示します。これはスタック トレースと呼ばれます。デバッグ情報 + Jedi CodeLibrary (Delphi IDE で使用される) madExcept、EurekaLog、synopse ログなどのいくつかの例外割り込みが存在します。

Delphi Win32 アプリケーションでコール スタックを表示する


DLL または EXE はランタイム パッケージを使用しますか?

于 2012-09-20T10:43:20.320 に答える