2010-07-31 5 views
1

quelqu'un peut me dire où je fais erreur dans la conversion:C à DELPHI convertir

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; 

du code c sizeof (REGISTRY_EVENT) = 36

à partir du code delphi sizeof (REGISTRY_EVENT) = 40

Merci à l'avance

Bojan

+1

Ident le code avec 4 places il obtient la syntaxe highlighing et une police à espacement fixe. C'est beaucoup plus facile de cette façon. – zz1433

Répondre

7

L'erreur est ici

registryData: array of UCHAR; 

Vous n'avez pas besoin d'un tableau dynamique ici.


Mise à jour:

Je suppose que

UCHAR registryData[]; 

est une entaille de C pour créer un champ de longueur nulle à la fin de la structure. Un bidouille équivalent Delphi est

registryData: record end; 

pour accéder à ce champ factice comme un tableau à Delphes, vous devez Typecast:

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; 

mais probablement vous devez typecast ce champ factice à autre chose puisque la définition du champ est juste un hack.

Et enfin: Ne jamais utiliser des tableaux dynamiques Delphi (comme registryData: tableau de UCHAR;) lors de la conversion des structures C à Delphi. Le tableau dynamique dans Delphi est un type de référence géré à vie qui n'a pas d'équivalent exact en C.

+0

RegistryData: tableau de char registrydata: array [0..0] de uchar registrydata: uchar tous sont avec la taille 40 –

+0

Bojan: supprime le tableau uchar en C et vérifie si la taille change. Sinon, c'est le problème. Il n'y a qu'un seul type avec un sizeof (x) = 0, à savoir "record end;" et il n'y a pas d'équivalent afaik pour que pascal ait un tableau de longueur zéro. IOW ce type de syntaxe C est un hack C-centric. –

+0

Merci beaucoup à tous. En utilisant un enregistrement vide, j'ai résolu le problème. Ce c structures, même RegistryData a et plus de 200 caractères larges a toujours la taille = 36. –

2

Je ne suis pas sûr que c'est une erreur - il peut bien être le compilateur d'insérer certains types de remplissage entre les champs. Essayez d'ajouter {$Align off} avant la définition d'enregistrement, ou modifiez = Record à = Packed Record et voyez si cela aide. Edit: même si cela peut aussi être un problème, la réponse de @ Serg me semble beaucoup plus probable.

+0

Et {$ Aligner off} et l'enregistrement condensé donne un mauvais résultat. avec enregistrement, pour l'heure Je reçois l'année = 0, le mois = 2010, le jour = 7, l'heure = 31, la minute = 22 etc. Mais le type d'événement et l'ID de processus sont corrects. –

+0

C'est la structure retournée par le pilote du noyau pour la surveillance du registre. Dans le registryData sont stockés le chemin du registre, les données, etc., et avec dataLength, registryPathLengthB définit les octets utilisés dans le registre. –

+0

en code c pour lire ceci est UINT offset = 0; do { /* e-> registryData contient d'abord le chemin du registre puis éventuellement certaines données */ 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); ... décalage + = taille de (REGISTRY_EVENT) + e-> registryPathLengthB + e-> dataLengthB; lorsque je diminue en delphi la ligne précédente pour 4 je reçois la chaîne des événements. –

0

Ceci est probablement dû à des tailles différentes des types de données de chaque champ ou à un remplissage différent. Pour les tailles de champs, imprimez le sizeof() ou la taille() pour chacun et comparez. Si elles sont toutes les mêmes, alors il s'agit de remplissage, et vous devrez peut-être trouver une option de compilateur pour l'ajuster.

C'est, si vous vous en souciez. Pourquoi vous souciez-vous si les tailles sont les mêmes?

+1

A priori, il se soucie car cette structure sera retournée par le système d'exploitation, et la taille étant fausse signifie que certains de ses champs ne coïncideront pas avec ce que le système d'exploitation envoie. –

1
UCHAR registryData[]; 

est

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

Avec les dossiers emballés et tableau emballé pour les types de la taille de _Registry_Event est égal à 34.

+0

taille de REG_NOTIFY_CLASS; = 4 TIME_FIELDS; = 16 Thandle; = 4 3 x ULONG; 3 x 4 = 12 UCHAR; 4 = Somme = 40 pas 34 –

+0

Si REG_NOTIFY_CLASS est de 4 octets de la taille de _Registry_Event est égal à 37. On notera que array [0..0] de UCHAR est égal à 1 octet et non pas quatre. – pani