如何将检索指针缓冲区结构转换为Delphi?
我正在使用Windows API,必须在Delphi如何将检索指针缓冲区结构转换为Delphi?,delphi,winapi,struct,delphi-xe2,code-conversion,Delphi,Winapi,Struct,Delphi Xe2,Code Conversion,我正在使用Windows API,必须在Delphi记录中重新创建。我想我已经记下来了,但是这一次有点混乱,我需要确保我做得对 这里是原来的C++结构: typedef struct RETRIEVAL_POINTERS_BUFFER { DWORD ExtentCount; LARGE_INTEGER StartingVcn; struct { LARGE_INTEGER NextVcn; LARGE_INTEGER Lcn; } Extents
记录中重新创建。我想我已经记下来了,但是这一次有点混乱,我需要确保我做得对
<>这里是原来的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中使用此结构时,它似乎确实起作用。但是,由于结构内部的这个结构数组,我有点犹豫我是否正确地做了这件事。这看起来正确吗?将文本项定义为文本项数组是错误的。这将它声明为动态数组,一种托管引用类型。您需要的是一个有界数组,如text的数组[x..y]
这个C声明相当奇怪,因为它被声明为一个只有一个元素的数组。如果要精确复制它,应该将其声明为text的数组[0..0]
范围字段是结构中内联的可变长度数组。实际结构将包含ExtentCount
元素。这里不能使用Delphi动态数组。事实上,您永远不能在互操作中使用Delphi动态数组
因此,将其声明为array[0..0]
,与C代码一样。为了访问它,您需要禁用范围检查。此记录的实际实例将在索引0..ExtentCount-1
中包含有效数据
对于整型,请将C中的DWORD
映射到Delphi中的DWORD
。C中的LARGE\u INTEGER
到Delphi中的LARGE\u INTEGER
。这两者都与DelphiInteger
不同。前者是无符号的,后者是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\u INTEGER
类型很难使用。您可能更愿意将这些字段声明为Int64
这种类型的结构总是由堆分配的。堆分配代码必须计算出适合可变长度数组中ElementCount
项所需的大小。如果要分配缓冲区,则需要单独定义类型的内部记录,以便可以方便地将其命名为传递给SizeOf
。如果API进行分配,则您可以如上所述。启动VCN、NextVcn和Lcn定义为大整数,在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 = record
case Integer of
0: ( LowPart: DWORD;
HighPart: Longint; );
1: ( QuadPart: LONGLONG);
end;
龙龙实际上只是一个Int64。您可以使用LowPart和Highpart或QuadPart访问此结构
希望这能有所帮助。几乎所有内容都已翻译。@TLama,我想这可能就是我的答案,只要“几乎”不是一个因素。我指的是Windows API中的几乎所有内容。这是一个可变长度的数组。但你不能这样声明。实际数组具有ExtentCount元素。+1,特别是对于您的编辑。我几乎总是给内部记录一个单独定义的类型。它使很多事情变得非常简单。随着记录方法的引入,我会在TRetrievalPointersBuffer
类型上添加一个方法,用于计算给定ExtentCount
@jeroen的总大小。在这个方法中,我会在外部记录中定义内部类型。当您知道数组的上限时,可以通过相应地声明数组将其放入堆栈中。不是针对这种特定情况,但是假设您有WCHAR Name[1]
,并且您知道它最多包含255个字符,那么您可以将该字段定义为Name:WCHAR[0..254]
。我将尝试重新说明-1。。。您可能知道元素的最大可能数量,或者您可能不关心实际信息,而只想知道元素的数量,或者您可能只关心元素计数小于定义总数时的信息。声明这种结构的数组元素的数量大于1,并因此将其放在堆栈中,这没有什么错。这不是api的问题,因为接受这种结构的api对传递的大小是否符合api头不感兴趣,而对实际使用的缓冲区大小不感兴趣。@Sertac在这种情况下,当遇到更多错误数据时,您可能会使用堆栈分配并反复调用。不过我还是会的。