Компонент Delphi THTTPRIO в модуле данных вызывает EInvalidPointer - PullRequest
0 голосов
/ 28 января 2019

В консольном приложении я поместил компонент THTTPRIO в модуль данных и вызвал службу SOAP - которая работает, как и ожидалось, но когда программа завершается, возникает ошибка неверного указателя.

Я пробовал два способапозвонить в веб-сервис.Сначала использовал приведение THTTPRIO к типу интерфейса мыльного сервера

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

Поскольку это завершилось исключением EInvalidPointer, я попробовал метод GetHello в сгенерированном модуле привязки.Приведенный ниже исходный код показывает вторую попытку.

Ошибка, по-видимому, вызвана двойной свободой.Как я могу получить доступ к веб-сервису и избежать двойного бесплатного?

Вывод в обоих случаях:

Ответ сервера: Hello, Delphi.

EInvalidPointer: недопустимая операция указателя

Код модуля 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.

ps: все работает нормально, если я создаю и настраиваю экземпляр HTTPRIO во время выполнения.Однако это также означает, что всю конфигурацию и подключение обработчиков событий нельзя выполнить в инспекторе объектов.

1 Ответ

0 голосов
/ 29 января 2019

Проблема в ссылке в HelloService на интерфейс Hello.Эта ссылка выходит из области видимости и освобождается в конце вашего метода класса.Ваш модуль данных, предоставляющий объект 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;
...