11

jpeg.TJPEGImage のクラス ヘルパーであるGabriel Corneanu のjpegexを使用したいと思います。これこれを読んで、 Delphi Seattle を超えると、jpegex のようにプライベート フィールドにアクセスできないことがわかりました (以下の例では FData)。David Heffernan が提案したように VMT をいじることは、私には到底できません。これを行う簡単な方法はありますか?

   type
  // helper to access TJPEGData fields
  TJPEGDataHelper = class helper for TJPEGData
    function  Data: TCustomMemoryStream; inline;
    procedure SetData(D: TCustomMemoryStream);
    procedure SetSize(W,H: integer);
  end;

// TJPEGDataHelper
function TJPEGDataHelper.Data: TCustomMemoryStream;
begin
  Result := self.FData;
end;
4

3 に答える 3

9

クラス ヘルパーと RTTI を組み合わせて使用​​することで、クラス ヘルパーを使用する以前のバージョンの Delphi と同じパフォーマンスを実現できます。

秘訣は、RTTI を使用して起動時にプライベート フィールドのオフセットを解決し、それをクラス varとしてヘルパー内に格納することです。

type 
  TBase = class(TObject)
  private  // Or strict private
    FMemberVar: integer;
  end;

type
  TBaseHelper = class helper for TBase // Can be declared in a different unit
  private
    class var MemberVarOffset: Integer;
    function GetMemberVar: Integer;
    procedure SetMemberVar(value: Integer);
  public
    class constructor Create;  // Executed automatically at program start
    property MemberVar : Integer read GetMemberVar write SetMemberVar;
  end;

class constructor TBaseHelper.Create;
var
  ctx: TRTTIContext;
begin
  MemberVarOffset := ctx.GetType(TBase).GetField('FMemberVar').Offset;
end;

function TBaseHelper.GetMemberVar: Integer;
begin
  Result := PInteger(Pointer(NativeInt(Self) + MemberVarOffset))^;
end;

procedure TBaseHelper.SetMemberVar(value: Integer);
begin
  PInteger(Pointer(NativeInt(Self) + MemberVarOffset))^ := value;
end;

ご覧のとおり、少し余分な入力が必要ですが、ユニット全体にパッチを適用する場合と比較すると、簡単です。

于 2016-06-16T14:26:23.940 に答える