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

Langage C++ Discussion :

Communication inter-logiciels avec pointeurs : la restriction orientée objet, ou le C++ pas si bas niveau


Sujet :

Langage C++

  1. #1
    Inactif  
    Homme Profil pro
    Collégien
    Inscrit en
    Octobre 2012
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Octobre 2012
    Messages : 78
    Points : 0
    Points
    0
    Par défaut Communication inter-logiciels avec pointeurs : la restriction orientée objet, ou le C++ pas si bas niveau
    Bon, OK, le titre est bizarre. Mais vous l'aurez compris, je voudrais vous parler de comment communiquer entre deux logiciels en utilisant les pointeurs. J'ai découvert les pointeurs il y a peu de temps en lisant un cours pour le C++. Et ils mettent en garde de toujours mettre son pointeur à 0 et que, si on utilise l'allocation dynamique, de remettre le pointeur à 0, afin de ne pas modifier les variables d'autres programmes. Ça m'a fait pensé à une chose : et si on communiquait entre deux programmes en provoquant volontairement cette erreur. Le programme "hôte" enregistrerait la variable et l'utilisateur devra récupérer la valeur du pointeur pour la donner dans le programme "invité". Les deux programmes pourront donc utiliser cette variable et communiquer avec, sur le principe de la boîte aux lettres. Le hic, c'est que je ne connais aucune manière de préciser quelle valeur utiliser pour notre pointeur. Est-ce-que vous en connaissez une, vous?

  2. #2
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Ce n'est pas une histoire de langage, mais une histoire d'OS. Un OS ne laisse pas un programme accéder comme ça à la mémoire d'un autre, sinon en cas de plantage ou de tentative de hackage, c'est toute la machine qui tomberait au lieu d'un programme en particulier.

    Il y a moyen à deux programmes de se partager explicitement de la mémoire, c'est ce qu'on nomme de la mémoire partagée (shared memory en anglais). Les API pour y accéder dépendent de l'OS, et il y a des différences entre OS aussi sur le comportement de cette mémoire.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  3. #3
    Inactif  
    Homme Profil pro
    Collégien
    Inscrit en
    Octobre 2012
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Octobre 2012
    Messages : 78
    Points : 0
    Points
    0
    Par défaut
    merci. mais alors, pourquoi le cours dit qu'on peut le faire? car comme je l'ai dit, il mets bien en garde qu'on doit délier le pointeur de la case mémoire après avoir libéré la mémoire. Et pareil quand il parle de déclarer un pointeur, il dit de le mettre à 0 au début, pour pas tomber sur une donnée au hasard.

  4. #4
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Citation Envoyé par sosolal Voir le message
    merci. mais alors, pourquoi le cours dit qu'on peut le faire?
    Probablement pour rajouter un peu d'effet dramatique

    Sur les PC et OS modernes, il y a des protections pour empêcher d’écrire n'importe où. Donc dans la réalité si tu accèdes à un pointeur nul, à un pointeur non initialisé ou plus généralement à un pointeur hors de l'espace mémoire dédié à ton process alors l'appli va crasher et tu auras une popup du style "Le programme a cessé de fonctionner".

  5. #5
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    Citation Envoyé par sosolal Voir le message
    Le hic, c'est que je ne connais aucune manière de préciser quelle valeur utiliser pour notre pointeur. Est-ce-que vous en connaissez une, vous?
    Les autres ont répondu à la motivation de ton post, mais je me permets de répondre à cette question précisément.
    Un pointeur est une variable qui contient une adresse. Cette adresse est une valeur numérique codée de nos jours sur 32 ou 64 bits. Rien ne t'empêche d'afficher cette valeur, avec un programme comme celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #include <iostream>
     
    int main (int argc, char **argv)
    {
    	int mavariable = 1981; // Valeur magique à transmettre à un autre processus
    	int *ptr_mavariable = &mavariable;
     
    	std::cout << "L'adresse de mavariable est " << ptr_mavariable << "\n";
     
    	std::cin.ignore (1);
     
    	return 0;
    }
    Il se trouve que ce programme affiche l'adresse puis attend que tu presses Entrée.
    Rien ne t'empêche alors, pendant que ce programme attend, de saisir l'adresse affichée dans un autre programme, le compiler, et le lancer. Un programme dans ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <iostream>
     
    int main (int argc, char **argv)
    {
       int *ptr_mavariable = (int*)0x2c7f90; // Chez moi, l'adresse affichée était celle là.
     
       std::cout << "Le contenu de la variable a l'adresse " << ptr_mavariable << " est " << *ptr_mavariable << "\n";
     
       std::cin.ignore (1);
     
       return 0;
    }
    Ce programme va surement planter. Même s'il venait à ne pas planter, je doute fort qu'il affiche "1981" comme contenu de variable.
    La raison, comme les autres ont expliqué, c'est que tu ne peux pas accéder à la mémoire d'un autre processus comme ça.

    L'explication, toutefois, est un peu plus complexe. En fait, sur un système moderne, la gestion de la mémoire est dite "virtuelle", c'est à dire que chaque processus à l'impression de disposer d'une quantité de mémoire aussi large que possible (4 giga octets pour un processus 32 bits), et pour lui tout seul. On appelle cette "quantité" l'espace d'adressage. Le système d'exploitation et le processeur travaillent ensemble pour que chaque fois qu'un processus demande à accéder à une certaine partie de cet espace, l'adresse est traduite vers une adresse réelle (en RAM cette fois).
    Même si ton processus essayait toutes les adresses l'une à la suite de l'autre, en partant de 0 jusqu'à 4 milliards, tu ne trouverais jamais la valeur 1981 (ou alors par hasard, tout simplement parce que la mémoire n'est pas initialisée et contient cette valeur).
    Du coup, dans mon expérience, l'adresse 0x2c7f90 est une adresse virtuelle. Elle n'a de sens que pour mon premier processus, où il a écrit 1981. La même adresse, pour un autre processus, pointe sur quelque chose de complètement différent.

    Maintenant, si deux processus veulent vraiment échanger des informations en utilisant la mémoire partagée, ils le peuvent, comme l'a dit JolyLoic.
    Dans ce cas, ce qui se passe, c'est que le système d'exploitation détecte que tu essayes d'accéder à une zone que tu avais déclaré "partagée". Et dans ce cas, il traduit l'adresse virtuelle vers la même partie de la RAM que celle qu'il avait donné à l'autre processus.
    Détail croustillant : comme les adresses sont virtuelles, elles ne sont pas forcément identiques, même dans ce cas de mémoire partagée. En gros, si les deux processus venaient à afficher l'adresse de ce qu'ils considèrent comme la mémoire partagée, ils afficheraient probablement deux adresses différentes.

    Je te conseille la lecture de l'article Wikipédia sur la mémoire virtuelle, si tu veux aller plus loin : http://fr.wikipedia.org/wiki/M%C3%A9moire_virtuelle

  6. #6
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Il y a toujours moyen d'echanger des donnees entre deux programmes de plusieurs facons :

    - reseau
    - fichier
    - pipe
    - shared memory
    - ...

    Le faire directement via des pointeurs est, comme l'ont dit les personnes qui t'ont deja repondu (pour des raisons de securite assez evidentes), impossible.

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Après, il est possible que ton OS offre des fonctions pour lire directement la mémoire d'un autre processus. Sous Windows, il faut avoir les droits sur le processus en question (par exemple, si les deux processus appartiennent au même utilisateur). Ainsi, l'exemple de phi1981 deviendrait:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include <windows.h>
    #include <iostream>
     
    int main (int argc, char **argv)
    {
    	int mavariable = 1981; // Valeur magique à transmettre à un autre processus
    	int *ptr_mavariable = &mavariable;
     
    	std::cout << "Mon ID de processus est " << GetCurrentProcessId() << std::endl;
    	std::cout << "L'adresse de mavariable est " << ptr_mavariable << std::endl;
     
    	std::cin.ignore (1);
     
    	return 0;
    }
    Et le programme où on place les valeurs hard-codées:
    Code C++ : 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
    #include <windows.h>
    #include <iostream>
    #include <cstdlib>
     
    int main (int argc, char **argv)
    {
    	DWORD processId = 42; //À remplacer par l'ID affiché
    	int *ptr_mavariable = (int*)0x2c7f90; // Chez moi, l'adresse affichée était celle là.
     
    	HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, processId);
    	if(hProcess == NULL) {
    		DWORD err = GetLastError();
    		std::cerr << "Echec d'ouverture du processus #" << processId << ": Erreur #" << err << std::endl;
    		return EXIT_FAILURE;
    	}
     
    	int mavariable_copy = 0;
    	if(!ReadProcessMemory(hProcess, ptr_mavariable, &mavariable_copy, sizeof(int), NULL)) {
    		DWORD err = GetLastError();
    		std::cerr << "Echec de lecture de la mavariable: Erreur #" << err << std::endl;
    		return EXIT_FAILURE;
    	}
    	CloseHandle(hProcess);
    	std::cout << "Le contenu de la variable a l'adresse " << ptr_mavariable << " est " << mavariable_copy << "\n";
     
    	std::cin.ignore (1);
     
    	return 0;
    }
    Je préviens, je n'ai pas compilé. Mais c'est à ça que ça ressemblerait, sous Windows.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Inactif  
    Homme Profil pro
    Collégien
    Inscrit en
    Octobre 2012
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Octobre 2012
    Messages : 78
    Points : 0
    Points
    0
    Par défaut
    Quelle est l'utilité de toute façon? Surtout avec la compléxité du code...

Discussions similaires

  1. communication pro-face avec un logiciel de supervision
    Par kaliza dans le forum Supervision
    Réponses: 0
    Dernier message: 29/04/2014, 16h01
  2. Communication inter-VLAN avec cisco 2960
    Par kineton dans le forum Équipements
    Réponses: 18
    Dernier message: 11/10/2013, 16h01
  3. Réponses: 3
    Dernier message: 08/06/2012, 00h09
  4. Communication inter threads avec boost
    Par MikeLarson dans le forum C++
    Réponses: 17
    Dernier message: 03/02/2012, 15h28
  5. Communication inter processus avec des sockets
    Par kek's dans le forum Réseau
    Réponses: 4
    Dernier message: 17/01/2011, 11h43

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