我在从线程的 XE/XE2 中使用 SOAP 时遇到问题。 (我没有使用较旧的 Delphis 对其进行测试。)在主线程中工作的简单代码在使用 无效指针操作
销毁 THTTPReqResp 实例时崩溃。
这是完整的程序。该表单仅包含一个触发 btnTestClick 事件的按钮:
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.
在 _FreeMem 调用的 TObject.FreeInstance 中引发异常。
procedure TObject.FreeInstance;
begin
CleanupInstance;
_FreeMem(Self);
end;
导致此问题的调用堆栈是
: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
我完全不知道发生了什么,为什么调用 _ClassDestroy 以及为什么代码崩溃:(有人可以 a) 解释我做错了什么 b) 修复我的代码吗?
最佳答案
“无效的指针操作”意味着您正在释放不代表有效内存的内容。这有时可能表明堆栈或堆损坏,但更有可能表明您正在释放已经释放的内容。
毫不奇怪_ClassDestroy
叫做。 FHTTPReqResp
是非空的,所以当 FreeAndNil
来电 Free
就在上面,Free
来电 Destroy
.
看来您的THTTPRIO
对象获得 THTTPReqResp
的所有权你给它。如果是这种情况,那么解决方案很简单:不要自己释放它。
关于multithreading - 无法销毁线程中的 THTTPReqResp 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8885455/