Delphi 数据模块上的 THTTPRIO 组件导致 EInvalidPointer

Delphi THTTPRIO component on datamodule causes EInvalidPointer

在控制台应用程序中,我将 THTTPRIO 组件放在数据模块上并调用 SOAP 服务 - 按预期工作,但当程序终止时,出现无效指针错误。

我试过两种调用网络服务的方法。首先将 THTTPRIO 转换为 soap 服务器接口类型

HelloService := (DM.HTTPRIO1 as Hello);
Response := HelloService.sayHello('Delphi');

由于 EInvalidPointer 异常终止,我在生成的绑定单元中尝试了 GetHello 方法。下面的源代码显示了第二次尝试。

该错误似乎是由双重释放引起的。如何访问网络服务并避免双重免费?

两种情况下的输出都是:

Server response: Hello, Delphi.

EInvalidPointer: Invalid pointer operation

datamodul单元代码为:

unit helloServiceDM;

interface

uses
  helloService,
  Classes, InvokeRegistry, Rio, SOAPHTTPClient;

type
  TDataModule1 = class(TDataModule)
    HTTPRIO1: THTTPRIO;
  public
    class procedure SayHello;
  end;

implementation

uses
  ActiveX, SysUtils;

{$R *.dfm}

{ TDataModule1 }

class procedure TDataModule1.SayHello;
var
  DM: TDataModule1;
  HelloService: Hello;
  Response: string;
begin
  ActiveX.CoInitialize(nil);

  DM := TDataModule1.Create(nil);
  try
    HelloService := GetHello(False, '', DM.HTTPRIO1);
    try
      Response := HelloService.sayHello('Delphi');
      WriteLn('Server response: ' + Response);
    except
      on E:Exception do
        Writeln(E.Classname, ': ', E.Message);
    end;
  finally
    DM.Free;
  end;

  ActiveX.CoUnInitialize;
end;

end.

p.s.: 如果我在运行时创建和配置 HTTPRIO 实例,一切正常。但是,这也意味着无法在对象检查器中完成事件处理程序的所有配置和连接。

问题是 HelloService 中对接口 Hello 的引用。此引用超出范围并在 class 方法结束时被释放。为接口提供 THTTPIO 对象的数据模块已在最后部分被销毁。

你必须在 finally 部分之前添加一个 HelloService := nil

DM := TDataModule1.Create(nil);
try
  HelloService := GetHello(False, '', DM.HTTPRIO1);
  try
    Response := HelloService.sayHello('Delphi');
    WriteLn('Server response: ' + Response);
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
  HelloService := nil; // <---- Add this
finally
  DM.Free;
end;