C到delphi的转换

时间:2010-07-31 18:29:22

标签: c windows delphi

有人可以告诉我在转换中我犯了哪些错误:

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

提前致谢

4 个答案:

答案 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()并进行比较。如果它们都是相同的,那么它就是填充,你可能需要找到一个编译器选项来调整它。

也就是说,如果你关心。你为什么关心尺寸是否相同?