1

我正在尝试在 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 中,它们显示为这样。

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 说如果模板没有在Delphi代码中实例化,就会发生这种情况。

但是,这里的问题是 -TMyObjectC++对象的后代TObject,所以我看不到如何从 Delphi 代码实例化模板。

有任何想法吗?

4

1 回答 1

2

你可以试试:

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 泛型的想法。

于 2013-09-19T19:32:16.030 回答