首页 > 解决方案 > 数据模块上的 Delphi THTTPRIO 组件导致 EInvalidPointer

问题描述

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

我尝试了两种调用 Web 服务的方法。首先使用了 THTTPRIO 到soap服务器接口类型的转换

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

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

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

两种情况下的输出都是:

服务器响应:你好,Delphi。

EInvalidPointer:无效的指针操作

数据模块单元代码为:

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.

ps:如果我在运行时创建和配置 HTTPRIO 实例,一切正常。然而,这也意味着事件处理程序的所有配置和连接都不能在对象检查器中完成。

标签: delphisoapfreedelphi-2009

解决方案


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

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

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;

推荐阅读