有人可以告诉我在转换中我犯了哪些错误:
C:
typedef struct _REGISTRY_EVENT {
REG_NOTIFY_CLASS eventType;
TIME_FIELDS time;
HANDLE processId;
ULONG dataType;
ULONG dataLengthB;
ULONG registryPathLengthB;
/* Contains path and optionally data */
UCHAR registryData[];
} REGISTRY_EVENT, * PREGISTRY_EVENT;
的Delphi:
_Registry_Event = record
EventType: REG_NOTIFY_CLASS;
Time: TIME_FIELDS;
processID: THandle;
DataType: ULONG;
DataLength: ULONG;
registryPathLength: ULONG;
registryData: array of UCHAR;
end;
来自c代码sizeof(REGISTRY_EVENT)= 36
来自delphi代码sizeof(REGISTRY_EVENT)= 40
提前致谢
博
答案 0 :(得分:7)
错误在这里
registryData: array of UCHAR;
这里不需要动态数组。
更新:
我认为
UCHAR registryData[];
是在结构末尾创建零长度字段的C hack。等效的Delphi hack是
registryData: record end;
要在Delphi中作为数组访问此虚拟字段,您应该进行类型转换:
type
PByteArr = ^TByteArr;
TByteArr = array[0..$FFFF] of Byte;
PRec = ^TRec;
TRec = packed record
Data: Integer;
MoreData: record end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
P: PRec;
PMoreData: PByteArr;
begin
P:= AllocMem(SizeOf(TRec) + 4);
PMoreData:= @P^.MoreData;
PMoreData^[2]:= 3;
ShowMessage(IntToStr(PMoreData^[2]));
FreeMem(P);
end;
但是你可能需要将这个虚拟字段强制转换为其他字段,因为字段定义只是一个黑客。
最后:从不使用Delphi动态数组(如registryData:UCHAR数组;)将C结构转换为Delphi 。 Delphi中的动态数组是一种生命周期管理的引用类型,在C中没有完全相同的。
答案 1 :(得分:2)
我不确定这是一个错误 - 编译器可能在字段之间插入一些填充。尝试在记录定义之前添加{$Align off}
,或将= Record
更改为= Packed Record
,看看是否有帮助。
编辑:虽然这也可能是一个问题,@ Serg的回答让我更有可能。
答案 2 :(得分:1)
UCHAR registryData[];
是
registryData: array[0..0] of UCHAR;
对于类型的打包记录和打包数组,_Registry_Event的大小等于34。
答案 3 :(得分:0)
这可能是由于每个字段的数据类型的大小不同,或者是由于填充不同。对于字段大小,请为每个字段打印sizeof()或size()并进行比较。如果它们都是相同的,那么它就是填充,你可能需要找到一个编译器选项来调整它。
也就是说,如果你关心。你为什么关心尺寸是否相同?