スレッドからXE/XE2でSOAPを使用する際に問題が発生しています。 (私は古いDelphisでテストしませんでした)Invalid pointer operation
でTHTTPReqRespインスタンスを破棄している間に、メインスレッドで動作する単純なコードがクラッシュします。スレッド内のTHTTPReqRespコンポーネントを破棄できません。
これは完全なプログラムです。例外が_FreeMem呼び出しでTObject.FreeInstanceに発生し
unit Unit79;
interface
uses
SysUtils, Forms, Classes, Controls, StdCtrls, ComObj,
ActiveX, InvokeRegistry, SOAPHTTPTrans, Rio, SOAPHTTPClient;
type
TForm79 = class(TForm)
btnTest: TButton;
procedure btnTestClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form79: TForm79;
implementation
{$R *.dfm}
procedure TForm79.btnTestClick(Sender: TObject);
begin
TThread.CreateAnonymousThread(
procedure
var
FHTTPReqResp: THTTPReqResp;
FHTTPRIO: THTTPRIO;
begin
if CoInitializeEx(NIL, COINIT_MULTITHREADED or COINIT_SPEED_OVER_MEMORY) = S_OK then try
FHTTPReqResp := THTTPReqResp.Create(nil);
with FHTTPReqResp do begin
Name := 'HTTPReqResp1';
UseUTF8InHeader := True;
InvokeOptions := [soIgnoreInvalidCerts, soAutoCheckAccessPointViaUDDI];
WebNodeOptions := [];
end;
FHTTPRIO := THTTPRIO.Create(nil);
with FHTTPRIO do begin
Name := 'HTTPRIO1';
HTTPWebNode := FHTTPReqResp;
end;
//
FreeAndNil(FHTTPRIO);
FreeAndNil(FHTTPReqResp); //<-- crashes here
finally CoUninitialize; end;
end
).Start;
end;
end.
:フォームはbtnTestClickイベントをトリガーする唯一のボタンが含まれています。
procedure TObject.FreeInstance;
begin
CleanupInstance;
_FreeMem(Self);
end;
この問題につながるコールスタックは_ClassDestroyがすべてで呼び出され、コードがクラッシュした理由:(誰かことができる理由、私は何が起こっている全く見当がつかない
:75bab9bc KERNELBASE.RaiseException + 0x58 System.TObject.FreeInstance System.ErrorAt(2,$4052E1) System.Error(reInvalidPtr) System.TObject.FreeInstance System._ClassDestroy(???) Soap.SOAPHTTPTrans.THTTPReqResp.Destroy System.TObject.Free frmMain.TMainForm.btnTestClick$4934$ActRec.$0$Body System.Classes.TAnonymousThread.Execute System.Classes.ThreadProc($F83530) System.ThreadWrapper($F51050) :76a4339a kernel32.BaseThreadInitThunk + 0x12 :77b59ef2 ntdll.RtlInitializeExceptionChain + 0x63 :77b59ec5 ntdll.RtlInitializeExceptionChain + 0x36
ですa)私が間違っていることを説明し、b)自分のコードを修正してください。
D2010にはまだCreateAnonymousThreadがありません。今すぐ非匿名で試してみてください。非匿名のスレッドではクラッシュしません。 –
スレッディングは問題ではない(私は思う)。それはOmniThreadLibrary(これは私がこの問題を見つけた方法でした)と同じクラッシュします。 – gabr
THttprioのドキュメントから、「nil(Delphi)またはNULL(C++)パラメータで作成すると、参照カウントがゼロになると自動的に破棄されます」。明示的に解放しています。 –