comprendre ce code en C

Sujets variés concernant le développement en PureBasic
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

comprendre ce code en C

Message par Anonyme2 »

Je me suis écrit un petit bout de code pour extraire des fichier h (de MS) les enumérations (c'est pour commencer, et puis c'est du code bourrin car c'est juste pour m'aider). Loin de moi l'idée de transcrire du C en Pure, je n'y connait pratiquement rien en C, je regarde le code et j'essaye de comprendre et puis li y a des sites d'explications en français.

Mon code marche pas trop mal, testé sur tous les fichiers h de gdi+ et le résultat est correct mais j'ai un problème de comphrésension

Les énumération en C commencent par le mot clef enum suivi du nom de l'énumération puis le symbole { déclenche le début de l'énumération et le symbole } termine l'énumération

voici le code C qui me pose problème, extrait du fichier GdiplusEnums.h

Code : Tout sélectionner

//---------------------------------------------------------------------------
// EMF+ Records
//---------------------------------------------------------------------------

// We have to change the WMF record numbers so that they don't conflict with
// the EMF and EMF+ record numbers.

enum EmfPlusRecordType;

#define GDIP_EMFPLUS_RECORD_BASE        0x00004000
#define GDIP_WMF_RECORD_BASE            0x00010000
#define GDIP_WMF_RECORD_TO_EMFPLUS(n)   ((EmfPlusRecordType)((n) | GDIP_WMF_RECORD_BASE))
#define GDIP_EMFPLUS_RECORD_TO_WMF(n)   ((n) & (~GDIP_WMF_RECORD_BASE))
#define GDIP_IS_WMF_RECORDTYPE(n)       (((n) & GDIP_WMF_RECORD_BASE) != 0)

enum EmfPlusRecordType
{
   // Since we have to enumerate GDI records right along with GDI+ records,
   // We list all the GDI records here so that they can be part of the
   // same enumeration type which is used in the enumeration callback.

    WmfRecordTypeSetBkColor              = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETBKCOLOR),
    WmfRecordTypeSetBkMode               = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETBKMODE),
    WmfRecordTypeSetMapMode              = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETMAPMODE),
    WmfRecordTypeSetROP2                 = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETROP2),
    WmfRecordTypeSetRelAbs               = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETRELABS),
Mon problème vient du fait que l'on a deux fois la ligne
enum EmfPlusRecordType
la 1ere fois suivi de définitions que je trouve jolies mais auxquelles je ne comprend strictement rien et la 2eme fois c'est l'énumération que je comprend

il y a quelqu'un à bord pour m'expliquer sans me renvoyer sur un forum C

Merci
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

# Syntaxe :

#define identificateur texte


# Description :

Cette directive permet de définir des pseudo-constantes. Elle remplace chaque occurrence de identificateur dans le programme C par la chaîne texte.

L'usage est de mettre les identificateurs des pseudo-constantes en majuscules.
# Exemple :

#define TAILLE 100
#define SAUT_DE_LIGNE putchar('\n')
#define THEN

apriori il sagit de definition de constante

tout comme nos : #DOBRO=255

mais je crois que cela correspond plus a nos Macro !
car le remplacement a l'air d'etre fait au moment du linkage

:D

pour ton probleme il te suffis d'attendre d'avoir le "{"
apres avoir eu le enum , pour extraire :D

tu met une variable_flag a 1 des que tu rencontre "enum"
puis tu la met a 2 des que tu as "{"

tu extrais seulement si egale a 2
puis tu la remet egale a zero si "}"!! :D

:D
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Merci Dobro mais je me demande pourquoi il y a 2 fois le même ligne, il y a bien une raison

J'ai adapté mon code pour ce type de cas.

Les constantes en C sont définies avec le mot const comme ceci par exemple

Code : Tout sélectionner

const float FlatnessDefault = 1.0f/4.0f;
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

la première est en fait une déclaration. après je ne connais pas son utilité car elle ne semble pas sollicitée entre la déclaration et le bloc enum enh lui-même...

pour les constantes de type "const", il me semble que ce sont des constantes qui sont compilées avec le reste du programme (la constante à une adresse, probablement une section .data readonly)

Dri
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Merci pour l'info Dri.

Pour l'instant je converti les const comme des constantes Pb, je vais réfléchir sur ce que ça pourrait entraîner comme changement.
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

Non, define c'est pas vraiment pour une constante, car on peut créer des fonctions avec. C'est plutot une macro.

Car on peut faire :

Code : Tout sélectionner

#define carre(x) (x*x)
Et dailleurs dans le code, ya des constantes et aussi des fonctions qui sont définies...

mais je ne comprend pas tout au code... :?
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

lionel_om,

en lisant ton message j'ai percuté sur ce que j'aui lu dans la doc MS sur cette enumeration. Je n'ai pas mis la liste car elle est longue et elle est formée de manière différente des autres énumération du fichier.

elles sont de la forme

Code : Tout sélectionner

WmfRecordTypeSetBkColor              = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETBKCOLOR),
En gros, Ms dit ceci sur cette enumération :

Les éléments qui ont le préfixe WmfRecordType se rapportent aux constantes définies dans le fichier Wingdi.h qui ont le prefixe META_. Par exemple, l'élément WmfRecordTypeSetBkColor est analogue à la constantes META_SETBKCOLOR

Les éléments qui ont le préfixe EmfRecordType se rapportent aux constantes définies dans le fichier Wingdi.h qui ont le prefixe EMR_. Par exemple, l'élément EmfRecordTypePolygon est analogue à la constantes EMR_POLYGON

Les éléments qui ont le préfixe EmfPlusRecordType sont spécifiques à Gdi+.

Les 3 defined (macros ?) définissent peut-être quelque choses pour ces 3 types différents (n = position dans la liste ?)
KarLKoX
Messages : 1191
Inscription : jeu. 26/févr./2004 15:36
Localisation : France
Contact :

Message par KarLKoX »

Simple hypothèse : le premier enum sert à récupérer l'énum en cours, c'est une sorte de copie que le linker va assigner avec la lib qui la définie ailleur de manière externe, une fois ceci fait, il suffit les champs qui nous interessent en modifiant les bits en utilisant différentes constantes qui serviront à manipuler les bits.
"Qui baise trop bouffe un poil." P. Desproges
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

KarLKoX, Je n'ai pas tout compris :roll:

Mon hypothèse

la première enum est terminé par un ; c'est donc une instruction et pas une enumeration au sens strict

Je pense que les lignes qui suivent définissent les paramètres utilisés par le précompilateur (macro-substitution) pour substituer les parametres par la premiere expression du define dans l'énumération réelle qui suivra.

C'est peut-être ce que tu voulais dire ?
KarLKoX
Messages : 1191
Inscription : jeu. 26/févr./2004 15:36
Localisation : France
Contact :

Message par KarLKoX »

Le premier enum est pour moi uniquement la pour le linker : en effet, si tu compiles un code C avec une variable externe, qui est résolue ailleur que dans ton code, par exemple dans une lib, le linker ne retournera aucune erreur car il aura tassé cette variable dans le code objet.
Donc mon hypothèse suit cette idée : une fois que le linker à résolu cette variable, en sous entendant que le programmeur ait bien ajouté la lib/code objet/code source dans son projet la définissant/utilisant, tu peux la manipuler pour en faire ce que tu veux.
Exemple : j'ai un fichier C main.c et un fichier main.h, dans main.h, je met "extern int foo;" dans la pratique, il faudrait que dans main.c je la mette en global via un "int foo;" mais je part de l'hypothèse que cela n'est pas fait et que foo est résolue ailleur que dans mon code, dans un autre fichier par exemple ou un fichier objet ou encore un fichier binaire (.lib/.a etc ...).
Ainsi, le compilateur retrouvera ses petits et compilera sans problème.
"Qui baise trop bouffe un poil." P. Desproges
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Ok et merci pour l'explication
Répondre