I am having problems using SOAP in XE/XE2 from a thread. (I didn't test it with older Delphis.) A simple code that works in the main thread crashes while destroying the THTTPReqResp instance with Invalid pointer operation
.
This is the complete program. The form contains only one button which triggers btnTestClick event:
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.
The exception is raised in TObject.FreeInstance on the _FreeMem call.
procedure TObject.FreeInstance;
begin
CleanupInstance;
_FreeMem(Self);
end;
The call stack leading to this problem is
: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
I have absolutely no idea what's going on, why _ClassDestroy is called at all and why the code crashes :( Can somebody please a) explain what I'm doing wrong and b) fix my code?
"Invalid pointer operation" means you're freeing something that doesn't represent valid memory. That can sometimes indicate stack or heap corruption, but it more likely indicates that you're freeing something that has already been freed.
It's no surprise that _ClassDestroy
is called. FHTTPReqResp
is non-null, so when FreeAndNil
calls Free
on it, Free
calls Destroy
.
It would appear that your THTTPRIO
object acquires ownership of the THTTPReqResp
you give it. If that's the case, then the solution is simple: don't free it yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With