IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

copie d'une struct avec pointeur


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de Thor Tillas
    Inscrit en
    Octobre 2006
    Messages
    113
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 113
    Par défaut copie d'une struct avec pointeur
    Bonjour bonjour,

    Nous sommes pauvres débutant en c++ qui essayont tant bien que mal d'utilisé les struct pour envoyé des informations par le réseau.

    Le but de notre envoi est de mettre dans une structure nommée gm_msg un id connection et les données qui ont été passées en paramètre à la méthode send (le paramètre est un char * nommée m).

    nous faisons donc un memcpy de m dans la partie data de gm_msg.

    Puis, nous devons copier ce gm_msg dans un buffer d'envoi. Ce buffer sera ensuite envoyé à notre serveur qui castera ce qu'il recoit en gm_msg et récupérera les data d'un coté et le id connection de l'autre.

    Notre probème est le suivant. Lors du memcpy de gm_msg dans le buffer d'envoi, il ne copie que le pointeur vers m et non pas les données de m. Donc sur le serveur, on récupère un pointeur sur quelque chose qui n'existe pas de ce coté du réseau.

    J'espère que j'ai été assez clair... En fait ce que l'on cherche c'est comment copier dans un buffer une structure contenant des pointeurs en prenant en compte la destination de ces pointeurs...

    Je vous me le code source pour si ca peut vous aider...

    Merci d'avance pour toute réponse (meme si c'est pour dire que mon post ne veut rien dire et que c'est imcompréhensible... d'ailleur je m'en excuse d'avance...)

    P.S. euh comme c'est mon premier post... ben euh... je sais pas trop si vous avez des conventions pour les titres de post, si j'ai le droit de poster ou je veux... bref si j'ai enfreint une règle je vous prie de m'excuser et je ferais le nécessaire pour corriger cette erreur...

    Notre code :

    Les structures :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    //structure passée en paramètre du Send
    typedef struct{
            unsigned int globalID;
            unsigned int portID;
    }gm_connect_msg;
    //structure contenant le message et l'idconnection que l'on va envoyé au serveur
    typedef struct{
            int idConn;
            char * data;
    }gm_msg;
    Voici la méthode send :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
    int paroc_combox_gm::Send(const char *m, int len){
    printf("[DEBUG]Init of Send(char*, int)\n");
      gm_recv_event_t *event;
      void *sendBuffer=NULL;
      int expected_callbacks=0;
      gm_status_t status;
      gm_msg msg;
      int length;
      printf("[DEBUG] variables sets, begin memcpy\n");
      gm_printf("[DEBUG] m param :%s, his lenght : %i \n",m,len);
      msg.data = (char *)malloc(len);
      memcpy(msg.data,m,len);
      printf("[DEBUG] end of memcpy \n");
      msg.idConn = idConn;
      length = sizeof(msg);
      /* Buffers are preallocated to CACTUS_MSG_SIZE other buffers need to be handled */
      nNextSendBuffer = (nNextSendBuffer + 1) % nSendTokens;
     
      printf("[DEBUG] End of init of send \n");
      gm_printf("[DEBUG] find a free buffer and send Token\n");
     
      if(gm_send_buffer[nNextSendBuffer].state != BUFFER_FREE){
        while(nNextSendBuffer < nSendTokens){
          nNextSendBuffer=(nNextSendBuffer+1) % nSendTokens;
          if(gm_send_buffer[nNextSendBuffer].state == BUFFER_FREE)
            break;
          }
          if(nNextSendBuffer==nSendTokens && gm_send_buffer[nNextSendBuffer].state==BUFFER_IN_USE){
            fprintf(stdout,"Not enough Tokens for send \n");
            return -1;
          }
      }
      printf("[DEBUG] free buffer ok!\n");
     
      sendBuffer=gm_send_buffer[nNextSendBuffer].data;
      printf("Len: %i\n", strlen(msg.data)+1);
     
      gm_printf("[DEBUG] registration of the message in buffer \n");
      memcpy(gm_send_buffer[nNextSendBuffer].data,&msg,length);
     
      gm_printf("DESTINATION : Node=%i ;Port=%i", destNodeID, destPortID);
     
      gm_send_with_callback(gm_port,sendBuffer,
                      gm_log2_roundup(MSG_SIZE),
                      length,GM_LOW_PRIORITY,
                      destNodeID,destPortID,
                      send_callback,
                      &gm_send_buffer[nNextSendBuffer]);
     
        fprintf(stdout,"Send-Msg Sent Message successfully\n");
        while (1){
          event = gm_receive (gm_port);
          switch (GM_RECV_EVENT_TYPE(event))
          {
            case GM_RECV_EVENT:
            case GM_PEER_RECV_EVENT:
            case GM_FAST_PEER_RECV_EVENT:
              gm_printf ("[send] Receive Event (UNEXPECTED)\n");
              status = GM_FAILURE; /* Unexpected incoming message */
              return -1;
     
            case GM_NO_RECV_EVENT:
             break;
     
            default:
             gm_unknown (gm_port, event);    /* gm_unknown calls the callback */
             return 0;
          }
        }
      return (GM_SUCCESS);
    }
    notre methode receive...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    int paroc_combox_gm::Recv(char * msg, int msgLength){
      printf("Recv() in Combox_gm\n");
      gm_recv_event_t *event;
      void *buffer;
      unsigned int size;
      int messages_expected = 1;
      unsigned int len;
      void * message;
      gm_msg m;
     
     
      gm_connect_msg tmpmsg;
      gm_connect_msg * tmpptr;
     
      printf("\t Init passed\n");
     
      while(messages_expected > 0){
        event = gm_receive (gm_port);
        //      fprintf(stdout,"Received an Event \n");
        switch (GM_RECV_EVENT_TYPE(event)){
        case GM_RECV_EVENT:
        case GM_PEER_RECV_EVENT:
        case GM_FAST_PEER_RECV_EVENT:
          printf("\tyou have a new message\n");
          len=gm_ntoh_u32(event->recv.length);
     
          memcpy(&m, gm_ntohp(event->recv.message), len);
     
     
          printf("\tm init\n");
          printf("idConn = %i\n",m.idConn);
     
          printf("\t tmp init\n");
          tmpptr = (gm_connect_msg *) m.data;
          printf("\tmsg copy done\n");
          printf("\tm.data : %s\n",m.data);
          printf("\tm.idConn : %d\n",m.idConn); //this is right
          printf("\ttmpptr.node : %d",tmpptr->nodeID);//this is wrong
     
          messages_expected--;
          /* Return the buffer for reuse */
          buffer = gm_ntohp (event->recv.buffer);
          size = (unsigned int)gm_ntoh_u8 (event->recv.size);
          gm_provide_receive_buffer (gm_port, buffer, gm_log2_roundup(MSG_SIZE),
                                     GM_LOW_PRIORITY);
          printf("\trecv buffer re-provided\n");
          break;
     
        case GM_NO_RECV_EVENT:
          break;
     
        default:
          gm_unknown (gm_port, event);      /* gm_unknown calls the callback */
        }
      }
    }

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Par défaut
    Effectivement c'est pas le bon forum. C'est pas du C++ mais du C ca

    Et pour ton problème, c'est tout à fait normal. Comment veux-tu que ca copie autre chose que ton pointeur?
    La seule solution est tout simplement la plus évidente: gérer toi même ce cas.
    Tu dois envoyer un chaine de bytes linéaire alors que la représentation en mémoire n'est pas linéaire. Prends ca en compte et ca fonctionnera.
    Sinon tu as la solution bête et mèchante: tu remplaces le char* par un char[UNE_CERTAINE_TAILLE].

  3. #3
    Membre confirmé Avatar de Thor Tillas
    Inscrit en
    Octobre 2006
    Messages
    113
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 113
    Par défaut
    ok... donc c'est bien ca qui foire... bon ben on va faire autrement alors... prions pour que ca passe en faisant un char contenant "idConn:msg" que l'on pourra parser de l'autre côté...


    Merci pour la réponse...

    (pour ce qui est question du C++ ou C... ben normalement ca devrait être du C++, mais j'avoue que cette partie du code est plus proche du C...)

  4. #4
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Et c'est un problème typique de la sérialisation. La FAQ C++ lite en parle plus en détail, sinon suivant les protocoles de codage, il y a moyen d'utiliser des bilbiothèques existantes.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct{
            int idConn;
            char * data;
    }gm_msg;
    Ne serait-ce pas plutôt char data[] dont tu as besoin ?

  6. #6
    Membre confirmé Avatar de Thor Tillas
    Inscrit en
    Octobre 2006
    Messages
    113
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 113
    Par défaut
    Merci pour toutes ces réponses. Finalement nous avons choisi de transformer un peu notre protocole.

    Au lieu de prendre une structure, nous avons décider de prendre un "string" contenant une première partie IdConn et une deuxième partie "msg".

    ex : "1:[kdsajfélkjdsélkfjédhféljkas]" ou [kdsajfélkjdsélkfjédhféljkas] est le "msg".

    Ce qui nous demande de faire un parsing, mais qui nous permet surtout de pas avoir de problème avec les pointeurs...

    Et c'est un problème typique de la sérialisation. La FAQ C++ lite en parle plus en détail, sinon suivant les protocoles de codage, il y a moyen d'utiliser des bilbiothèques existantes.
    l'embettant c'est que c'est un protocole pour les réseaux mirinet (utilisé sur les réseaux de cluster) donc tout est propriétaire... et bien sur rien ne se rapproche de ce que l'on veut... comme toujours...

    Voilà, encore merci à tous et j'espère pouvoir vous rendre la pareil un de ces jours

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2003] Copie d'une formule avec VBA
    Par akane dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 15/09/2009, 19h32
  2. appel d'une fonction avec pointeur comme argument
    Par airness86180 dans le forum Débuter
    Réponses: 1
    Dernier message: 06/03/2009, 13h34
  3. copie d'une table avec une requete
    Par funboard dans le forum Oracle
    Réponses: 2
    Dernier message: 20/01/2009, 16h02
  4. copie d'une arborescence avec excel vb
    Par kernel57 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 18/11/2005, 08h31
  5. [VBA] Copie d'une feuille (avec graphique)
    Par ed_dexia dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 06/10/2005, 09h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo