Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2005 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Après "Pimp My Ride" ....."Cast my struct" !!

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Après "Pimp My Ride" ....."Cast my struct" !!

n°1569890
in_your_ph​ion
Posté le 04-06-2007 à 16:40:30  profilanswer
 

Salut,

 

Alors voila, il était une fois ....

 

......et ceci amenant cela, je fus rapidement confronté a un problème de programmation en C.

 

...

 

Donc, je ne comprend pas comment marche les casts sur les structures. J'ai vu un exemple sur le net de programmation générique, ou la personne recherche à passer une structure générique à une fonction, pour une application client-serveur á développer contenant une centaine de formats de trames différentes.

 

http://www.developpez.net/forums/s [...] p?t=345137

 


Je met  le code ici pour que ce soit plus clair :

 
Code :
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. typedef struct Frame { 
  5. void (*send_data)();
  6. } Frame_s; 
  7. typedef struct GenericFrame { 
  8. Frame_s frame;
  9. } GenericFrame_s; 
  10. typedef struct FrameA { 
  11. Frame_s frame;
  12. int n;
  13. } FrameA_s;
  14. typedef struct FrameB {
  15. Frame_s frame;
  16. char str[20];
  17. } FrameB_s; 
  18. typedef struct FrameC {
  19. Frame_s frame;
  20. double f;
  21. } FrameC_s;
  22. void sendDataFrameA(FrameA_s * frame) { 
  23. printf("I send the frame A with n=%d\n", frame->n);
  24. }
  25. void sendDataFrameB(FrameB_s * frame) {
  26.   printf("I send the frame B with string:%s\n", frame->str);
  27. }
  28. void sendDataFrameC(FrameC_s * frame) { 
  29.   printf("I send the frame C with f=%lf\n", frame->f);
  30. }
  31. int main(void) {
  32. GenericFrame_s * frames[3];
  33.   FrameA_s * fA = NULL;
  34.   FrameB_s * fB = NULL; 
  35.   FrameC_s * fC = NULL;
  36.   int i; 
  37.   /* TODO : Verifier allocations*/ 
  38.   fA = malloc(sizeof(*fA));
  39.   fB = malloc(sizeof(*fA));
  40.   fC = malloc(sizeof(*fA)); 
  41.   fA->frame.send_data = sendDataFrameA;
  42.   fA->n = 51; 
  43.   fB->frame.send_data = sendDataFrameB;
  44.   strcpy(fB->str, "hello" );
  45.    fC->frame.send_data = sendDataFrameC;
  46.    fC->f = 13.2; 
  47.   frames[0] = (GenericFrame_s*)fA;
  48.   frames[1] = (GenericFrame_s*)fB;
  49.   frames[2] = (GenericFrame_s*)fC;
  50.   for(i=0; i<3; ++i) {
  51.        frames[i]->frame.send_data(frames[i]);
  52.   } 
  53.  
  54.   free(fA);
  55.   free(fB);
  56.   free(fC);
  57.   return 0;
  58. }
 


Je comprend ce que fais le programme mais pas vraiment le concept, notamment les casts :

Code :
  1. frames[0] = (GenericFrame_s*)fA;
  2.   frames[1] = (GenericFrame_s*)fB;
  3.   frames[2] = (GenericFrame_s*)fC;
 

alors que les structures ne sont pas les mêmes. Quelqu'un pourrait-il m'expliquer comment marches les cast avec des structures, est ce risqué ou est ce normal ??? Est ce que cette démarche est valide.

 

Je ne comprend pas bien non plus le :

Code :
  1. frames[i]->frame.send_data(frames[i]);
 

on envoi a la structure sa structure ?

 

merci par avance  :jap:

Message cité 1 fois
Message édité par in_your_phion le 04-06-2007 à 16:46:42
mood
Publicité
Posté le 04-06-2007 à 16:40:30  profilanswer
 

n°1569929
cgo2
Dum spiro spero
Posté le 04-06-2007 à 17:12:34  profilanswer
 

in_your_phion a écrit :

alors que les structures ne sont pas les mêmes. Quelqu'un pourrait-il m'expliquer comment marches les cast avec des structures, est ce risqué ou est ce normal ??? Est ce que cette démarche est valide.


 
C'est pas la structure qui est castée, c'est le pointeur. Et si je dis pas de connerie, un pointeur est toujours un pointeur, quelque soit l'élément sur lequel il pointe (tu verras souvent des fonctions prendre en paramètre un void *).
 

in_your_phion a écrit :

on envoi a la structure sa structure ?


 
Oui parceque le C n'est pas un langage objet et que le mot clef "this" n'existe pas. Alors il faut bien passer le contexte en paramètre...
 
 


---------------
When it's from Finland it's good.  - Mon blog
n°1569947
el muchach​o
Comfortably Numb
Posté le 04-06-2007 à 17:38:07  profilanswer
 

Ce genre de chose est en effet risqué vu qu'avec un cast, on bypasse la vérification du typage par le compilo, il faut donc bien calculer son coup et être sûr que les données reçues seront à tous les coups couvertes par l'un des cas prévus, sinon, on arrive rapidement à un crash.
Souvent, dans ce genre de cas, on essaye de faire une union, qui permet une vérification statique. Mais ça reste tout de même rare, parce que c'est plutôt crade, c'est effectivement utile quand on essaye de minimiser les données à transmettre ou sauvegarder (mais dans ce cas, je choisirais un algo de compression plutôt qu'un hack à base cast/union/void *). Et dans l'exemple ci-dessus, ça me parait assez extrême.

Message cité 1 fois
Message édité par el muchacho le 04-06-2007 à 17:41:09
n°1569956
cgo2
Dum spiro spero
Posté le 04-06-2007 à 17:56:31  profilanswer
 

el muchacho a écrit :

Et dans l'exemple ci-dessus, ça me parait assez extrême.


 
Ca c'est clair, l'exemple ci-dessus c'est comment essayer de faire de l'objet en C (y'a même une vague notion d'héritage)...


---------------
When it's from Finland it's good.  - Mon blog
n°1569960
0x90
Posté le 04-06-2007 à 18:17:13  profilanswer
 

Code :
  1. typedef struct FrameA {  
  2.   Frame_s frame;
  3.   int n;
  4. } FrameA_s;


Comme tu peut le voir, ta structure FrameA a comme premier membre une structure Frame_s.
 
Si tu as

Code :
  1. FrameA* un_pointeur = &FrameA_s;


ton pointeur pointe vers le début de la structure FrameA_s, c'est à dire qu'il pointe sur son premier membre, si tu caste ton pointeur avec le type du premier membre, tu accèdera correctement à ce premier membre :

Code :
  1. Frame_s* un_autre_pointeur = (Frame_s*)un_pointeur;
  2. // C'est pareil que :
  3. Frame_s* un_autre_pointeur = &(un_pointeur->frame);


Fait un dessin avec des boiboites, tu verra que c'est logique.


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Après "Pimp My Ride" ....."Cast my struct" !!

 

Sujets relatifs
Qu'est-ce "(struct addr_in *) mavariable" ?HELP! Parser un fichier de conf et renvoyer vers struct
[Java-Corba] Problème de castPorbleme avec des string dans une struct....
polymorphisme sur un struct en C++[Résolu] modification d'une struct managée par un filtre directshow
Types de cast en C++Cast en VBS
arraylist transtypage cast object string int (help please)prob avec struct sockaddr_in et inet_addr
Plus de sujets relatifs à : Après "Pimp My Ride" ....."Cast my struct" !!


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)