2018/9/22 (土) 07:37:53 Mr.XRAY |
[DLL上の例外をコピーした文字列をFreeLibraryにアクセスとエラーになる]
http://madia.world.coocan.jp/cgi-bin/DelphiBBS/wwwlng.cgi?print+201809/18090005.txt
の関連ですが,taka さんが Lazarus でテストしたというので,
C++ で DLL を作成してテストしてみました.
DLL の作成には Visual C++ 2013 を使用しました.
Delphi では .dpr ファイルを 1 つ提供すれば,それをコンパイルして DLL が作成
できますが,VC++ ではそうはいかないので DLL を添付しています.
ランタイムライブラリもリンクしていますから,VC++ がインストールされていない
環境でもテスト可能です.以下は TestDll.cpp のコードです.
添付の TestDll.dll は y = 4; の例外発生なし,
TestDll_div0.dll は y = 0; の例外発生ありです.
#include "stdafx.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
EXPORT int TestFunc()
{
int x;
int y;
x = 100;
y = 0;
return x / y;
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
DLL を使用する Delphi のテスト用コードです.
IDE から実行するとメモリアクセス違反の例外が発生しますが,
エラーの文字列は表示されます.
EXE 単独実行の場合は例外のダイアログは現れません.
動作確認は Windows 7 U64(SP1) + Delphi XE5(UP2) Pro です.
Ansi 版 (非ユニコード版) の Delphi でコンパイルすると表示文字が化けます.
procedure TForm1.Button1Click(Sender: TObject);
var
DLLExecute : function : Integer; stdcall;
ModuleHandle : HModule;
TPExecute : TFarProc;
LInt : Integer;
LErrStr : string;
begin
Memo1.Lines.Clear;
ModuleHandle := LoadLibrary('TestDll_div0.DLL'); // 0除算用DLLのロード
// ModuleHandle := LoadLibrary('TestDll.DLL');
if ModuleHandle <> 0 then
begin
TPExecute := GetProcAddress(ModuleHandle, 'TestFunc');
if (TPExecute <> nil) then
begin
@DLLExecute := TPExecute;
try
LInt := DLLExecute;
Memo1.Lines.Add(IntToStr(LInt));
except
on E: Exception do
begin
LErrStr := PChar(E.Message);
end;
end;
end;
Memo1.Lines.Add(LErrStr);
FreeLibrary(ModuleHandle);
Memo1.Lines.Add(LErrStr);
end;
end;
http://mrxray.on.coocan.jp/Delphi/zip/QandA_20180920_dllException.zip
|
|