【问题标题】:Delphi Generics with C++ Builder Types带有 C++ 生成器类型的 Delphi 泛型
【发布时间】:2013-08-25 10:48:17
【问题描述】:

我正在尝试在 C++Builder 应用程序中使用 SuperObject 进行 JSON 编组。

SuperObject 有一些通用函数可以帮助解决这个问题:

  TSuperRttiContext = class
  ...
    function AsType<T>(const obj: ISuperObject): T;
    function AsJson<T>(const obj: T; const index: ISuperObject = nil): ISuperObject;
  end;

在生成的 .hpp 中,它们显示为 this。

class PASCALIMPLEMENTATION TSuperRttiContext : public System::TObject
{
    ...
    template<typename T> T __fastcall AsType(const _di_ISuperObject obj);
    template<typename T> _di_ISuperObject __fastcall AsJson(const T obj, const _di_ISuperObject index = _di_ISuperObject());
};

到目前为止一切都很好。我可以像这样编译代码

TMyObject * myObject = ...;
_di_ISuperObject obj = superRttiContext->AsJson(myObject);

String s = obj->AsString();

但是,我无法链接它。

[ILINK32 Error] Error: Unresolved external 'System::DelphiInterface<Superobject::ISuperObject> __fastcall Superobject::TSuperRttiContext::AsJson<TMyObject *>(const TMyObject * const, const System::DelphiInterface<Superobject::ISuperObject>)' referenced from C:\FOO.OBJ

现在,这并不完全出乎意料:Embarcadero DocWiki says this will happen 如果模板没有在 Delphi 代码中实例化。

但是,问题出在 - TMyObject 是一个从 TObject 继承的 C++ 对象,所以我看不到如何从 Delphi 代码中实例化模板。

有什么想法吗?

【问题讨论】:

  • 您可以在 C++ 中使用 JSON 读取器/写入器;见stackoverflow.com/questions/3512650/…
  • 能否在 Delphi 中创建一个类似的对象来代替 TMyObject,然后使用生成的 .hpp 文件中生成的 C++ 等效项?

标签: delphi generics c++builder


【解决方案1】:

你可以试试:

a) 在 Delphi 中,为 TSuperRttiContext 创建一个适配器。

type
  TAdapterSuperObject<T : class> = class
    constructor Create();
    destructor Destroy(); override;
    function ObjectToJson(value : T) : String;
    function JsonToObject(value : String) : T;
  end;

function TAdapterSuperObject<T>.JsonToObject(value: String): T;
var
  iso : ISuperObject;
  ctx : TSuperRttiContext;
begin
  ctx := TSuperRttiContext.Create;
  try
    try
    iso := SO(value);
      Result := ctx.AsType<T>(iso)
    except
      on e: Exception do
        raise Exception.Create('JsonToObject error: ' + e.Message);
    end;
  finally
    iso := Nil;
    ctx.Free;
  end;
end;

function TAdapterSuperObject<T>.ObjectToJson(value: T): String;
var  
  ctx : TSuperRttiContext;
begin
  ctx := TSuperRttiContext.Create;
  try
    try
    Result := ctx.AsJson<T>(value).AsString;
    except
      on e: Exception do
        raise Exception.Create('ObjectToJson error: ' + e.Message);
    end;
  finally
    ctx.Free;
  end;
end;

b) 使用适配器声明您的类并在 c++ 中使用它们

type
  TAdapterInfo = class(TAdapterSuperObject<TInfo>);

c) 最后,在 c++ 中调用适配器:

TAdapterSuperObject__1<TInfo*>* adapterInfo = new TAdapterSuperObject__1<TInfo*>();
...
adapterCliente->ObjectToJson(aInfo);
...

基本上这就是我在 c++ 中使用和使用 Delphi 泛型的想法。

【讨论】:

  • 谢谢——这让我深思!在步骤 B 中,这是否意味着您可以为刚刚前向声明的 C++ 类实例化 Delphi 模板?
猜你喜欢
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
  • 2014-11-13
  • 1970-01-01
  • 2013-04-09
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多