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 代码一样声明它。为了访问它,您需要禁用范围检查。此记录的实际实例将在 indices 中包含有效数据0..ExtentCount-1

对于您的整数类型,将DWORDC 中的映射到DWORDDelphi 中。并LARGE_INTEGER在C到LARGE_INTEGERDelphi中。这些都与 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

定义TExtentsarray of TExtent错误。那就是将它声明为一个动态数组,一种托管引用类型。你需要的是一个有界数组,比如array [x..y] of TExtent.

不过,这个 C 声明相当奇怪,因为它被声明为一个只有一个元素的数组。 如果要准确复制它,则应将其声明为array [0..0] of TExtent.

于 2012-10-06T20:31:07.183 回答
2

StartingVcn、NextVcn 和 Lcn 定义为 LARGE_INTEGER,在 winnt.h 中定义如下:

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 回答