喫茶XRAYトップページ

[スレッド全体
]

[12326] Re2:DLL内の関数で発生した例外の捕捉返信 削除
2018/9/22 (土) 16:56:33 Mr.XRAY
▼ takaさん

> PChar(E.Message);
> だと
> コンパイラの最適化方法に依存するので
> LErrStr := E.Message;
> などの代入後に
> UniqueString(LErrStr);
> をいれて確実に参照カウンタ1のユニークなアドレスを持つようにする必要があるとわかりました。
>
> http://docwiki.embarcadero.com/RADStudio/Berlin/ja/%E6%96%87%E5%AD%97%E5%88%97%E5%9E%8B%EF%BC%88Delphi%EF%BC%89


おおっ〜 !!
知りませんでした.いやはや.ありがとうございます.
早速コード修正して再 UP します.


[12329] UniqueString返信 削除
2018/9/22 (土) 17:25:21 Mr.XRAY
> UniqueString(LErrStr);

なんでもやってみると,ということでやってみました.
使用した DLL は以下の質問者が提示したコードです.

[DLL上の例外をコピーした文字列をFreeLibraryにアクセスとエラーになる]
http://madia.world.coocan.jp/cgi-bin/DelphiBBS/wwwlng.cgi?print+201809/18090005.txt

DLL を使用する Delphi のコードです.
UniqueString を使用しない場合です.

procedure TForm1.Button1Click(Sender: TObject);
var
  DLLExecute   : function : Integer; stdcall;
  ModuleHandle : HModule;
  TPExecute    : TFarProc;
  S            : string;
  LInt         : Integer;
begin
    ModuleHandle := LoadLibrary('DUMMY.DLL');
    if ModuleHandle <> 0 then
    begin
      TPExecute  := GetProcAddress(ModuleHandle, 'Execute');
      if (TPExecute <> nil) then
      begin
        @DLLExecute := TPExecute;
        try
          LInt := DLLExecute;
        except
          on E: Exception do
          begin
            S := E.Message;
          end;
        end;
      end;
      Memo1.Lines.Add(S);
      // 以下のコードが実行されないので,メモリリークが発生する
      FreeLibrary(ModuleHandle);
      Memo1.Lines.Add(S);
    end;
end;

デバッガ例外通知で [継続] をクリックすると何回かデバッガ例外通知となります.
最後に下図のように表示されます.
動作確認は Windows 7 U64(SP1) + Delphi XE5(UP2) Pro VCL-32 です.


[12330] Re:UniqueString返信 削除
2018/9/22 (土) 17:30:35 Mr.XRAY
続いて UniqueString を使用する場合です.

procedure TForm1.Button1Click(Sender: TObject);
var
  DLLExecute   : function : Integer; stdcall;
  ModuleHandle : HModule;
  TPExecute    : TFarProc;
  S            : string;
  LInt         : Integer;
begin
    ModuleHandle := LoadLibrary('DUMMY.DLL');
    if ModuleHandle <> 0 then
    begin
      TPExecute  := GetProcAddress(ModuleHandle, 'Execute');
      if (TPExecute <> nil) then
      begin
        @DLLExecute := TPExecute;
        try
          LInt := DLLExecute;
        except
          on E: Exception do
          begin
            S := E.Message;
            UniqueString(S);
          end;
        end;
      end;
      Memo1.Lines.Add(S);
      // 以下が実行されるのでメモリリークは発生しない
      FreeLibrary(ModuleHandle);
      Memo1.Lines.Add(S);
    end;
end;

デバッガ例外通知で [継続] をクリックすると下図のように表示されます.
例外通知は 1 回だけです.
EXE の直接起動では例外通知は表示されません.
動作確認は Windows 7 U64(SP1) + DelphiXE5(UP2) Pro VCL-32 です.


[12331] 一連のテストの注意返信 削除
2018/9/22 (土) 17:33:37 Mr.XRAY
テストプロジェクトをダウンロード可能にして,更にテストをしていますが,
そのようなことをしてもいいということではありません.
あくまでも,興味としてのテストです.


[12342] Re:一連のテストの注意返信 削除
2018/9/23 (日) 11:40:18 Mr.XRAY
> そのようなことをしてもいいということではありません.
> あくまでも,興味としてのテストです.


もし,某掲示板の質問者が作成した DLL を使用しなければならなくなった時,
その DLL 内での例外を捕捉できるか ?
という課題とも言えます.


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82