2010-07-31 186 views
1

有人可以告訴我在哪裏,我在轉換犯錯誤:C到德爾福轉換

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; 

德爾福:

_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

from delphi code sizeof(REGISTRY_EVENT)= 40

在此先感謝

博揚

+1

訂貨號用4個空間,以便它得到語法highlighing和等寬字體的代碼類型。這樣就容易多了。 – zz1433 2010-07-31 18:34:23

回答

7

的錯誤是在這裏

registryData: array of UCHAR; 

你並不需要一個動態數組在這裏。


更新:

我假定

UCHAR registryData[]; 

是C劈在結構的端部以產生一個零長度字段。等效德爾福黑客是

registryData: record end; 

訪問此虛擬場作爲德爾福數組,你應該強制轉換:

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; 

,但可能需要強制轉換這個虛擬場到別的東西,因爲字段定義只是一個黑客。而轉換C結構對Delphi;

最後::從不使用Delphi動態數組(UCHAR的陣列等registryData)。 Delphi中的動態數組是一種生命週期管理的參考類型,在C中沒有完全等效的參考類型

+0

RegistryData:char數組 uchar的registrydata:array [0..0] registrydata:uchar 所有大小都爲40 – 2010-07-31 20:27:14

+0

Bojan:刪除C中的uchar數組,並查看大小是否更改。 如果不是,那就是問題所在。 sizeof(x)= 0只有一種類型,即「記錄結束」;並且pascal有一個沒有等價的長度爲零的數組。 IOW這種C語法是以C爲中心的黑客攻擊。 – 2010-07-31 22:36:09

+0

非常感謝所有人。使用空記錄我解決了這個問題。這c結構,甚至RegistryData有更多然後20​​0寬字符的大小總是= 36. – 2010-08-01 05:18:09

2

我不知道這是一個錯誤 - 它可能是編譯器插入域之間的一些填充。嘗試在記錄定義之前添加{$Align off},或將= Record更改爲= Packed Record並查看是否有幫助。

編輯:雖然這也可能是一個問題,但@塞爾格的答案讓我感覺更有可能。

+0

和{$關閉}並打包記錄會導致錯誤的結果。 與記錄,爲時間我接收年= 0,月= 2010年,日= 7,小時= 31,分= 22等但事件類型和進程ID是正確的。 – 2010-07-31 20:20:36

+0

這是從內核驅動程序返回的用於註冊表監視的結構。在registryData中存儲註冊表路徑,數據等,並用dataLength,registryPathLengthB定義註冊表數據中使用的字節。 – 2010-07-31 20:21:01

+0

在讀取此代碼的c代碼是 UINT offset = 0;註冊表數據首先包含註冊表路徑,然後可選地包含一些數據* PREGISTRY_EVENT e =(PREGISTRY_EVENT)(registryEventsBuffer + offset); BYTE * registryData = NULL; wchar_t * szRegistryPath = NULL; szRegistryPath =(wchar_t *)malloc(e-> registryPathLengthB); CopyMemory(szRegistryPath,e-> registryData,e-> registryPathLengthB); ... offset + = sizeof(REGISTRY_EVENT)+ e-> registryPathLengthB + e-> dataLengthB; 當我在delphi中減少前一行4我正在接收事件鏈。 – 2010-07-31 20:22:19

0

這可能是由於每個字段的數據類型的大小不同或者由於不同的填充引起的。對於字段大小,爲每個字段打印sizeof()或size(),並進行比較。如果它們完全相同,那麼它是填充,並且您可能需要找到一個編譯器選項來調整它。

也就是說,如果你在乎。爲什麼你在意尺寸是否相同?

+1

有人猜測,他關心的是因爲這個結構將被操作系統返回,而錯誤的大小意味着他的某些字段不會與操作系統發送的內容重合。 – 2010-07-31 18:44:25

1
UCHAR registryData[]; 

registryData: array[0..0] of UCHAR; 

具有壓縮記錄和堆積陣列爲_Registry_Event的大小等於34

+0

大小 REG_NOTIFY_CLASS; = 4 TIME_FIELDS; = 16 THandle; = 4 3 x ULONG; 3×4 = 12 UCHAR; = 4 Sum = 40 not 34 – 2010-08-01 06:03:25

+0

如果REG_NOTIFY_CLASS是4個字節,則_Registry_Event的大小等於37. 請注意,UCHAR的數組[0..0]等於1個字節而不是4個。 – pani 2010-08-01 06:52:33