Delphi XE和Unicode

时间:2015-06-19 20:10:04

标签: delphi unicode delphi-xe

我有一个在Delphi 6中工作的函数。现在我尝试将旧项目迁移到Delphi XE8,但是这个函数不能正常工作。

请帮帮我。

旧功能:

function ReadString(var P: Pointer): String;
var
  B: Byte;
begin
  B := Byte(P^);
  SetLength(Result, B);
  P := Pointer( Integer(P) + 1);
  Move(P^, Result[1], Integer(B));
  P := Pointer( Integer(P) + B );
end;

我尝试将其更改为取消编码,但它不起作用:

function ReadString(var P: Pointer): String;
var
  B: Byte;
  LResult: AnsiString;
begin
  B := Byte(P^);
  SetLength(LResult, B);
  P := Pointer( Integer(P) + 1);
  Move(P^, LResult[1], Integer(B));
  P := Pointer( Integer(P) + B );
  Result := String(LResult);
end

该功能用于:

GetIntfMetaData(Myobj as IFController,IntfMD,True);

    procedure GetIntfMetaData(Info: PTypeInfo; var IntfMD: TIntfMetaData; MethodArrayOpt: TFillMethodArrayOpt);
var
  I, Offset: Integer;
  Methods: Integer;
  BaseRTTIMethods: Integer;
  HasRTTI: Integer;
  PP: PPTypeInfo;
  P: Pointer;
  SelfMethCount: Integer;
  IntfMethod: PIntfMethEntry;
begin
  P := Pointer(Info);
  IntfMD.Info := Info;
  { tkKind }
  ReadByte(P);
  IntfMD.Name := ReadString(P);
   { Interface flags }
  ReadByte(P);
  IntfMD.UnitName := ReadString(P);
  Methods := ReadWord(P);   { # methods }
  HasRTTI := ReadWord(P);   { $FFFF if no RTTI, # methods again if has RTTI }
  if HasRTTI = $FFFF then
    raise EInterfaceRTTIException.CreateFmt(SNoRTTI, [IntfMD.UnitName + '.' + IntfMd.Name]);
  { Save my method count }
  SelfMethCount := Methods;
    Offset := 0;
  { Size array and fill in information }
  SetLength(IntfMD.MDA, Methods);
  FillMethodArray(P, @IntfMD, Offset, SelfMethCount);
end;

procedure FillMethodArray(P: Pointer; IntfMD: PIntfMetaData; Offset, Methods: Integer);
var
  S: Ansistring;
  I, J, K, L: Integer;
  ParamCount: Integer;
  Kind, Flags: Byte;
  ParamInfo: PTypeInfo;
  ParamName: Ansistring;
  IntfMethod: PIntfMethEntry;
  IntfParam: PIntfParamEntry;
begin
  for I := 0 to Methods -1 do
  begin
    IntfMethod := @IntfMD.MDA[Offset];
    IntfMethod.Name := ReadString(P);
    Kind := ReadByte(P);           { tkKind }
    IntfMethod.CC := CCMap[ReadByte(P)];
    ParamCount := ReadByte(P);     { Param count including self }
    IntfMethod.ParamCount := ParamCount - 1;
    IntfMethod.Pos := Offset;
    IntfMethod.HasRTTI := True;

    SetLength(IntfMethod.Params, ParamCount);
    K := 0;
    for J := 0 to ParamCount - 1 do
    begin
      Flags := ReadByte(P);       { Flags }
      ParamName := ReadString(P); { Param name }
      S := ReadString(P);         { Param type name }
      L := ReadLong(P);           { Param Type Info }
      if L <> 0 then
        ParamInfo := PPTypeInfo(L)^
      else
        raise EInterfaceRTTIException.CreateFmt(SNoRTTIParam, [ParamName, IntfMethod.Name, IntfMD.UnitName + '.' + IntfMd.Name]);
      if J = 0 then
        IntfMethod.SelfInfo := ParamInfo
      else
      begin
        IntfParam := @IntfMethod.Params[K];
        IntfParam.Flags := TParamFlags(Flags);
        IntfParam.Name := ParamName;
        IntfParam.Info := ParamInfo;
        Inc(K);
      end;
    end;
    if Kind = Byte(mkFunction) then
    begin
      S := ReadString(P);
      IntfMethod.ResultInfo := PPTypeInfo(ReadLong(P))^;
    end;
    Inc(Offset);
  end;
end;

function ReadByte(var P: Pointer): Byte;
begin
  Result := Byte(P^);
  P := Pointer( Integer(P) + 1);
end;

2 个答案:

答案 0 :(得分:3)

如果您希望通过PTypeInfo结构输入类型名称:

function GetName(p: Pointer): String;
begin
  Result := PTypeInfo(P)^.Name;
end;

或者更好地完全限定指针:

function GetName(p: PTypeInfo): String;
begin
  Result := P^.Name;
end;

或使用内置功能: TypInfo.GetTypeName

大卫在评论中指出,TTypeInfo记录以枚举Kind开头。接下来是Name字符串。此字段的偏移最好留给编译器计算。

在更新的问题中,很明显在调用函数获取名称之前,使用1(ReadByte)递增指针。不要这样做。 这样做:

IntfMD.Name := GetTypeName(Info);

现在,使用这些知识来处理TTypeInfo的方法,这也需要更新。

答案 1 :(得分:0)

这是我在互联网上找到的解决方案,但它有效(但我不知道它是否合适):<​​/ p>

chat.on