2

私は Windows API を使用しており、Delphi 内に構造を再作成するrecord必要があります。私はそれを落としたと思いますが、これは少し混乱していたので、これを正しく行ったことを確認する必要があります.

元の C++ 構造は次のとおりです。

typedef struct RETRIEVAL_POINTERS_BUFFER {
  DWORD         ExtentCount;
  LARGE_INTEGER StartingVcn;
  struct {
    LARGE_INTEGER NextVcn;
    LARGE_INTEGER Lcn;
  } Extents[1];
} RETRIEVAL_POINTERS_BUFFER, *PRETRIEVAL_POINTERS_BUFFER;

この構造体内に配列構造体があることに注意してください。ここで迷子になりました。私が間違っていなければ、Delphi のバージョンは次のようになります。

  TExtent = record
    NextVcn: Integer;
    Lcn: Integer;
  end;

  TExtents = array of TExtent;

  PRETRIEVAL_POINTERS_BUFFER = ^TRETRIEVAL_POINTERS_BUFFER;
  TRETRIEVAL_POINTERS_BUFFER = record
    ExtentCount: DWORD;
    StartingVcn: Integer;
    Extents: TExtents;
  end;

Windows API でこの構造を使用すると、機能しているように見えます。しかし、この構造体配列が構造体内にあるため、これを正しく行ったかどうか少しためらっています。これは正しく見えますか?

4

3 に答える 3

6

このExtentsフィールドは、構造体にインライン化された可変長配列です。実際の構造体にはExtentCount要素が含まれます。ここではDelphi動的配列を使用できません。実際、相互運用でDelphi動的配列を使用することはできません。

array [0..0]したがって、 Cコードと同じように宣言します。アクセスするには、範囲チェックを無効にする必要があります。このレコードの実際のインスタンスには、インデックスに有効なデータがあります0..ExtentCount-1

整数型の場合DWORDは、CDWORDでDelphiにマップします。そしてLARGE_INTEGERCLARGE_INTEGERでDelphiで。どちらもDelphiと同じではありませんInteger。前者は符号なしで、後者は64ビット幅です。

PRetrievalPointersBuffer = ^TRetrievalPointersBuffer;
TRetrievalPointersBuffer = record
  ExtentCount: DWORD;
  StartingVcn: LARGE_INTEGER;
  Extents: array [0..0] of record
    NextVcn: LARGE_INTEGER;
    Lcn: LARGE_INTEGER;
  end;
end;

タイプはLARGE_INTEGER扱いにくいです。代わりに、これらのフィールドを宣言することをお勧めしますInt64


このタイプの構造体は、常にヒープに割り当てられます。ヒープ割り当てコードは、ElementCountアイテムを可変長配列に収めるために必要なサイズを計算する必要があります。バッファを割り当てる場合は、に渡すために便利な名前を付けることができるように、個別に定義されたタイプの内部レコードが必要になりますSizeOf。APIが割り当てる場合は、上記のように問題ありません。

于 2012-10-06T20:46:10.467 に答える
2

StartedVcn、NextVcn、およびLcnは、winnt.hで次のように定義されているLARGE_INTEGERとして定義されています。

typedef union _LARGE_INTEGER {
    struct {
        DWORD LowPart;
        LONG HighPart;
    } DUMMYSTRUCTNAME;
    struct {
        DWORD LowPart;
        LONG HighPart;
    } u;
    LONGLONG QuadPart;
} LARGE_INTEGER;

使用しているDelphiのバージョンによっては、定義した構造が機能しない場合があります。LARGE_INTEGERは、次のように宣言する必要があります。

LARGE_INTEGER = record
  case Integer of
    0: ( LowPart: DWORD;
      HighPart: Longint; );
    1: ( QuadPart: LONGLONG);
end;

LONGLONGは実際には単なるInt64です。この構造には、LowPartとHighpartまたはQuadPartを使用してアクセスできます。

お役に立てれば。

于 2012-10-06T20:46:13.103 に答える
2

TExtentsとして定義するarray of TExtentのは間違いです。これは、動的配列、管理された参照型として宣言しています。必要なのは、のような有界配列ですarray [x..y] of TExtent

ただし、このC宣言は、要素が1つしかない配列として宣言されているという点でかなり奇妙です。 正確にコピーしたい場合は、として宣言する必要がありますarray [0..0] of TExtent

于 2012-10-06T20:31:07.183 に答える