加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

如何将对象转换为Delphi中泛型类型约束的接口

发布时间:2020-12-15 09:20:45 所属栏目:大数据 来源:网络整理
导读:我需要与一系列.Net Web服务进行交互.目前大约有150个. 由于delphi 2010使用Thttprio来实现这一点,我试图在客户端创建一个通用代理,可以调用它来创建适当的soap服务客户端. 有谁知道如何将httprio对象转换为通用接口类型? 谢谢 下面是我正在尝试使用的代理
我需要与一系列.Net Web服务进行交互.目前大约有150个.
由于delphi 2010使用Thttprio来实现这一点,我试图在客户端创建一个通用代理,可以调用它来创建适当的soap服务客户端.
有谁知道如何将httprio对象转换为通用接口类型?

谢谢

下面是我正在尝试使用的代理函数:

class function Web.Proxy<T>(svc: string): T;
var
  HTTPRIO : THTTPRIO;
begin
  HTTPRIO := THTTPRIO.Create(nil);
  HTTPRIO.URL := GetServiceURL(svc);
  Result:= HTTPRIO as T; //<-- Fails with "operator not applicable to this operand type"
  // Result:= T(HTTPRIO); //<-- also fails,but with "invalid typecast"
end;

我的想法是,我可以这样称呼:

Web.Proxy<AutmobileServiceSoap>('svc.asmx').GetAutomobile(125);

WSDL导入的AutmobileServiceSoap定义如下:

AutmobileServiceSoap = interface(IInvokable)

并且所有wsdl导入都有一个以类似方式返回httprio对象的函数:

function GetAutomobileServiceSoap(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): AutomobileServiceSoap;
const
  defWSDL = 'http://localhost:8732/Cars.Server/Data/AutomobileService.asmx?WSDL';
  defURL  = 'http://localhost:8732/Cars.Server/Data/AutomobileService.asmx';
  defSvc  = 'AutomobileService';
  defPrt  = 'AutomobileServiceSoap12';
var
  RIO: THTTPRIO;
begin
  Result := nil;
  if (Addr = '') then
  begin
    if UseWSDL then
      Addr := defWSDL
    else
      Addr := defURL;
  end;
  if HTTPRIO = nil then
    RIO := THTTPRIO.Create(nil)
  else
    RIO := HTTPRIO;
  try
    Result := (RIO as AutomobileServiceSoap);
    if UseWSDL then
    begin
      RIO.WSDLLocation := Addr;
      RIO.Service := defSvc;
      RIO.Port := defPrt;
    end else
      RIO.URL := Addr;
  finally
    if (Result = nil) and (HTTPRIO = nil) then
      RIO.Free;
  end;
end;

解决方法

您必须使用RTTI来获取接口的GUID

type
  Web = class
    class function Proxy<T: IInterface>(svc: string): T;
  end;

class function Web.Proxy<T>(svc: string): T;
var
  HTTPRIO: THTTPRIO;
  data: PTypeData;
begin
  HTTPRIO := THTTPRIO.Create(nil);
  HTTPRIO.URL := GetServiceURL(svc);
  data := GetTypeData(TypeInfo(T));
  if ifHasGuid in data.IntfFlags then
  begin
    HTTPRIO.QueryInterface(data.Guid,Result);
  end;
end;

如果指定IInterface约束,则可以确定T始终是接口(否则您还必须检查TypeInfo的TypeKind).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读