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

Windows Discussion :

Comment passer une map sur un named pipe windows ?


Sujet :

Windows

  1. #1
    Membre du Club Avatar de masterx_goldman
    Inscrit en
    Mai 2008
    Messages
    164
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 164
    Points : 51
    Points
    51
    Par défaut Comment passer une map sur un named pipe windows ?
    Bonjour tout le monde,

    J'ai deux processus P1 et P2 qui tournent dans deux comptes différents sur le même pc (pour mon cas, l'un dans le compte SYSTEM et l'autre dans le compte user ) et qui veulent s'échanger des informations. un des deux récolte les informations qu'il a dans une map stl " std::map<string,vector<string>> ma_map", et veut envoyer ce contenu vers l'autre processus.

    Alors j'aimerai bien savoir si la communication entre les deux peut se réduire à échanger une référence sur la map ou bien je vais m'acharner à encoder le contenu de la map sous format string puis la reconstruire de l'autre côté ?

    Pour écrire sur le pipe les processus utilisent la fonction writefile, voici la doc msdn:

    BOOL WINAPI WriteFile(
    __in HANDLE hFile,
    __in LPCVOID lpBuffer,
    __in DWORD nNumberOfBytesToWrite,
    __out_opt LPDWORD lpNumberOfBytesWritten,
    __inout_opt LPOVERLAPPED lpOverlapped
    );
    pBuffer [in]

    A pointer to the buffer containing the data to be written to the file or device.

    This buffer must remain valid for the duration of the write operation. The caller must not use this buffer until the write operation is completed.
    Plus précisement, est ce que le type LPCVOID ici permettra de pointer une map stl pour la transmettre en entier à l'autre processus ? et si c'est vrai , comment je fais ça dans l'émission(je passe &ma_map ... ?) et dans la réception( casting vers map ..? )
    Merci pour votre aide

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 059
    Points : 12 095
    Points
    12 095
    Par défaut
    Il faut "serialiser" la map dans le contexte de l'émetteur, puis écrire le résultat dans le fichier.
    Puis Il faut "déserialiser" la map dans le contexte du récepteur.

    Boost semble avoir ce qu'il faut pour sérialiser une map de la STL.
    http://khayyam.developpez.com/articl...serialization/

  3. #3
    Membre du Club Avatar de masterx_goldman
    Inscrit en
    Mai 2008
    Messages
    164
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 164
    Points : 51
    Points
    51
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Il faut "serialiser" la map dans le contexte de l'émetteur, puis écrire le résultat dans le fichier.
    Puis Il faut "déserialiser" la map dans le contexte du récepteur.

    Boost semble avoir ce qu'il faut pour sérialiser une map de la STL.
    http://khayyam.developpez.com/articl...serialization/
    J'ai précisé dans le titre de la question que la communication de fait à travers un pipe en utilisant la fonction writefile .. on est bien daccord que c'est la même chose ?
    Je suis entrain de lire l'article ..

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 059
    Points : 12 095
    Points
    12 095
    Par défaut
    Sérialiser, c'est convertir un objet en chaîne de caractère donc pipe ou fichier c'est pareil.
    Pour la portabilité, entre l'émetteur et le récepteur, il peut avoir des problèmes si boost n'utilise pas une représentation standard type XML.

  5. #5
    Membre du Club Avatar de masterx_goldman
    Inscrit en
    Mai 2008
    Messages
    164
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 164
    Points : 51
    Points
    51
    Par défaut
    Juste une remarque svp, j'aimerai bien que vous m'expliquiez le résultat de test que j'ai fait :
    Dans le code de l'émetteur j'ai mis:
    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
    // je remplie la map par un contenu de test
    map<CString,vector<CString>> ma_map;
    	 vector<CString> v; v.push_back("b");v.push_back("c");
    	 ma_map["a"]=v;
    // j'essai de passer une référence sur la map( puisque la fonction writefile prend un LPVOID comme param en entrée
    BOOL bResult = WriteFile( 
              hPipe,                // handle to pipe 
              &ma_map,             // buffer to write from 
              sizeof(ma_map)+1,   // number of bytes to write, include the NULL
              &cbBytes,             // number of bytes written 
              NULL);                // not overlapped I/O 
         
         if ( (!bResult) || (sizeof(ma_map)+1 != cbBytes))
         {
              printf("\nError occurred while writing to the server: %d", GetLastError()); 
              CloseHandle(hPipe);
              return 1;  //Error
         }
         else
         {
              printf("\nWriteFile() was successful.");
         }
    Alors le résultat de débuggage m'écrit
    WriteFile() was successful.
    Dans le code du récepteur , j'ai mis:
    1er test)
    ******
    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
    // je déclare une map pour recevoir l'autre map qui va "venir" sur le pipe
    map<CString,vector<CString>> ma_map;
    BOOL bResult = ReadFile( // this function is gona wait until something is read from the pipe
              hPipe,                // handle to pipe 
              &ma_map,             // buffer to receive data 
              sizeof(ma_map),     // size of buffer 
              &cbBytes,             // number of bytes read 
              NULL);                // not overlapped I/O 
         
         if ( (!bResult) || (0 == cbBytes)) 
         {
              printf("\nError occurred while reading from the client: %d", GetLastError()); 
              CloseHandle(hPipe);
              return 1;  //Error
         }
         else
         {
    		 
              printf("\nReadFile() was successful.");
         }
    Le résultat du debogage me donne erreur de GetLastError() 234 ce qui signifie sur msdn
    ERROR_MORE_DATA
    234 (0xEA) More data is available.
    et quand j'ajoute 1 à la taille du buffer(car dans l'emetteur la taille écrite est sizeof(ma_map)+1),
    2ème test)
    ******
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    // je déclare une map pour recevoir l'autre map qui va "venir" sur le pipe
    map<CString,vector<CString>> ma_map;
    BOOL bResult = ReadFile( // this function is gona wait until something is read from the pipe
              hPipe,                // handle to pipe 
              &ma_map,             // buffer to receive data 
              sizeof(ma_map)+1,     // size of buffer 
              &cbBytes,             // number of bytes read 
              NULL);                // not overlapped I/O
    La lecture réussit, car le retour de la fonction est non nul, le récepteur écrit le message de succès
    ReadFile() was successful.
    et le nombre d'octects lus est non nul
    cbBytes=29
    mais la map est "vide", pour être plus précis , elle n'est pas vide mais contient
    ma_map = [1](...)
    puis quand je développe ça avec le debogueur de VS je trouve que cet élement est
    (error) = 0
    Bon à vrai dire, j'avoue que le sizeof(ma_map)+1 chez le récepteur n'est pas la même que chez l'émetteur car chez l'émetteur elle est pleine et chez le récepteur elle est "vide" initialement..
    Bon, voilà j'ai essayé de donner le maximum de détails pour voir la possiblité de faire un petit réglage pour arriver au but. Sinon, si vous m'affirmez que y'a pas possiblité de réaliser mon but de cette façon, je vais faire comme a cité bacelar et me plonger dans la sérisalisation

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 059
    Points : 12 095
    Points
    12 095
    Par défaut
    C'est marqué où qu'une map est un objet contenue dans un bloc CONTINU en mémoire, et qu'il n'y a pas de pointeurs (éminent non transférable entre processus) et que les objets contenus dans la map sont dans ce bloc mémoire ?

  7. #7
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 352
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 352
    Points : 20 359
    Points
    20 359
    Par défaut
    masterx_goldman encore une fois c'est un problème de persistence des objets.
    Quand tu fais par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    vector<CString> v; v.push_back("b");v.push_back("c");
    le vecteur v effectue une copie d'instance de type CString.
    Elle n'est locale qu'à ton processus A !

    Citation Envoyé par masterx_goldman Voir le message
    Plus précisement, est ce que le type LPCVOID ici permettra de pointer une map stl pour la transmettre en entier à l'autre processus ?
    N'utilise pas des variables allouées localement sur la pile mais plutot des pointeurs ; donc tu dois allouer un pointeur de type std::map * avec un new et pareil pour les types contenus par le std::map.
    Si tu passes des pointeurs au pipe de communication tu passeras des objets et zones mémoires valides puisqu'elles pointeront sur des variables allouées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    map<CString,vector<CString>> ma_map;
    	 vector<CString> v; v.push_back("b");v.push_back("c");
    	 ma_map["a"]=v;
    // j'essai de passer une référence sur la map( puisque la fonction writefile prend un LPVOID comme param en entrée
    C'est normal que dans le processus tu ne recoives rien !
    WriteFile va fonctionner et donner un code de retour de succès.
    Mais tu ne recevras rien parce que tu alloues localement un std::map dans une fonction ce que l'on appelle allouer sur la pile.
    Donc lorsque ta fonction est terminée là ou tu alloues la std::map la std::map n'est plus valide.
    Seule solution que tu alloues des pointeurs globalement avec des new.
    Ou bien en static

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 059
    Points : 12 095
    Points
    12 095
    Par défaut
    Citation Envoyé par Mat.M Voir le message
    Seule solution que tu alloues des pointeurs globalement avec des new.
    Ou bien en static
    L'instance d'une map utilise en interne des pointeurs, qui n'ont aucune signification dans le processus receveur.
    Il faut SERIALISER la map.

  9. #9
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 352
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 352
    Points : 20 359
    Points
    20 359
    Par défaut
    Citation Envoyé par bacelar Voir le message
    L'instance d'une map utilise en interne des pointeurs, qui n'ont aucune signification dans le processus receveur.
    Il faut SERIALISER la map.
    Oui mais de toute façon passer des pointeurs à un pipe de communication n'est pas une bonne chose non plus...sinon le processus receveur risque de pointer sur des zones invalides.
    Quant à sérialiser c'est possible mais je trouve un peu lourd cette méthode parce que c'est une méthode intermédiaire un peu inutile, tu vas rajouter une étape supplémentaire.
    Si tu as une centaine max d'entrées dans la std::map ça va; si tu en as des milliers c'est pas une bonne méthode parce que le disque dur va être sollicité ce sera des opérations I/O supplémentaires.
    La solution la plus simple et la plus triviale c'est bêtement de parcourir la std::map dans le processus A , envoyer les entrées via le pipe et reconstituer une autre std::map dans le processus B.

  10. #10
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 352
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 352
    Points : 20 359
    Points
    20 359
    Par défaut
    Citation Envoyé par bacelar Voir le message
    Sérialiser, c'est convertir un objet en chaîne de caractère donc pipe ou fichier c'est pareil.
    je ne suis pas du tout d'accord ; un pipe c'est une sorte de zone mémoire d'intercommunication et la persistence n'est pas la même que pour un fichier texte sur disque.
    Les OS gèrent de manière différente les blocs de zone mémoire pas comme les fichiers sur disque.
    Maintenant masterx_goldman n'a qu'à tenter différentes choses..

    et puis peux-tu m'expliquer comment tu fais pour sérialiser les données et puis les envoyer dans le pipe ? .

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 059
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 059
    Points : 12 095
    Points
    12 095
    Par défaut
    Citation Envoyé par Mat.M Voir le message
    Quant à sérialiser c'est possible mais je trouve un peu lourd cette méthode parce que c'est une méthode intermédiaire un peu inutile, tu vas rajouter une étape supplémentaire.
    Si tu as une centaine max d'entrées dans la std::map ça va; si tu en as des milliers c'est pas une bonne méthode parce que le disque dur va être sollicité ce sera des opérations I/O supplémentaires.
    La solution la plus simple et la plus triviale c'est bêtement de parcourir la std::map dans le processus A , envoyer les entrées via le pipe et reconstituer une autre std::map dans le processus B.
    Citation Envoyé par Mat.M
    je ne suis pas du tout d'accord ; un pipe c'est une sorte de zone mémoire d'intercommunication et la persistence n'est pas la même que pour un fichier texte sur disque.
    Les OS gèrent de manière différente les blocs de zone mémoire pas comme les fichiers sur disque.
    Maintenant masterx_goldman n'a qu'à tenter différentes choses..
    Sérialisation n'a rien à voir avec les I/O. Cela est fait uniquement en mémoire. C’est tellement commun comme tâche que des librairies comme Boost ont des fonctionnalités qui convertissent un objet de la STL en chaîne de caractère. Tout le code de parcour est donc inutile puisque Boost sans charge. La sérialisation n’est pas lourde, bien au contraire.
    On a une chaine de caractères, un tableau de char, que l’on donne directement au pipe d’un coup.

Discussions similaires

  1. Comment passer un CString sur un pipe ?
    Par masterx_goldman dans le forum Windows
    Réponses: 2
    Dernier message: 16/09/2009, 21h22
  2. Réponses: 0
    Dernier message: 24/07/2007, 01h03
  3. Réponses: 15
    Dernier message: 25/06/2007, 10h35
  4. [Info]Comment mettre une servlet sur le web?
    Par fred9510 dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 15/08/2004, 17h40
  5. [icone]Comment appliquer une icone sur le.exe
    Par JavaLeDirePartout dans le forum JBuilder
    Réponses: 7
    Dernier message: 24/07/2003, 18h28

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