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++Builder Discussion :

Utilisation de mémoire partagé avec une structure


Sujet :

C++Builder

  1. #1
    Membre actif Avatar de Masmeta
    Homme Profil pro
    Ing. R&D informatique industrielle
    Inscrit en
    Mai 2006
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Ing. R&D informatique industrielle
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 472
    Points : 221
    Points
    221
    Par défaut Utilisation de mémoire partagé avec une structure
    Bonjour !

    Je me casse la tête sur la compréhension de la mémoire partagée.
    J'ai lu et relu ce tuto

    Mais je me pose beaucoup de question, et je ne sais pas comment mettre en oeuvre.

    Mon but est simple. C'est de pouvoir communiquer entre un service de com, avec une application, des données sous forme d'une structure.
    Je suis parti donc sur le filemapping.


    1. Comment faire pour partager ma structure commune aux 2 applications, sans créer un fichier ?

    2. Lors de la création de ma mémoire partagé par mon service comment communiqué l'adresse de départ à mon application?

    Cordialement

  2. #2
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Seine Maritime (Haute Normandie)

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Points : 578
    Points
    578
    Par défaut
    Hello,

    Si j'ai bien pigé, l'exemple que tu cites permets de créer un FileMapping à partir du fichier. Toi ce dont tu aurais besoin, c'est de créer un FileMapping sans fichier ?
    Tu peux assez facilement adapter la classe TMMF, le but étant de pouvoir appeler CreateFileMapping de la façon suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        FFileMap=CreateFileMapping(INVALID_HANDLE_VALUE, // handle to file to map       <================
            NULL, // optional security attributes
            PAGE_READWRITE, // protection for mapping object
            0, // high-order 32 bits of object size
            FTaille, // low-order 32 bits of object size => Taille de la structure partagée
            <Nom du mapping>); //
    genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    protected:
    ...
    int FTaille;
    AnsiString FNomMapping;
    ....
     
    public:
    ...
    __fastcall TMMF(AnsiString nomMapping, int taille);
    ....
    Le nouveau constructeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    __fastcall TMMF::TMMF(AnsiString nomMapping, int taille)
        :FFileMap(NULL),
        FFileHandle(INVALID_HANDLE_VALUE),   //  <============
        FMappingPtr(NULL),
        FFileSize(0),
        FFileSizeHigh(0),
        FFileName(""),
        FErrorMsg(""),
        FNomMapping(nomMapping),   // <=========
    FTaille(taille)    // TODO: rajouter FTaille(0) dans les autres constructeurs
    {
       // TODO: Ne pas faire CloseHandle(FFileHandle) dans le destructeur si FFileHandle == INVALID_HANDLE_VALUE ????
    }
    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
    void __fastcall TMMF::GetMapping()
    {
      char* pNom = NULL;
      if (!FNomMapping.IsEmpty())
         pNom = FNomMapping.c_str();
     
        FFileMap=CreateFileMapping(FFileHandle, // handle to file to map
     
            NULL, // optional security attributes
            PAGE_READWRITE, // protection for mapping object
            0, // high-order 32 bits of object size
            FTaille, // low-order 32 bits of object size              <======
            pNom); //                                             <============
     
        if (!FFileMap)
        RaiseLastOSError();
     
    }
    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
    bool __fastcall TMMF::Execute()
    {
        try
        {
            if (!FFileName.IsEmpty())
              GetFile();
            GetMapping();
            GetPtrAdresse();
            }
        catch (EOSError &E)
        {
            FErrorMsg=E.Message;
            return false;
            }
         if (!FFileName.IsEmpty())
           GetSizeofFile();
        return true;
     
    }
    Puis ensuite l'utilisation, depuis l'un ou l'autre de tes exe, pour récupérer un pointeur sur tes données partagées:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    TMMF * myMMF = new TMMF("NOM UNIQUE DU PARTAGE", sizeof(TMesDonnees));
    myMMF->Execute();
    TMesDonnees* pMesDonnees = (TMesDonnees*)myMMF->PtrMapping;
    pMesDonnes->.... = ...;
    Je n'ai rien testé, j'espère qu'il n'y a pas trop de conneries !!

  3. #3
    Membre actif Avatar de Masmeta
    Homme Profil pro
    Ing. R&D informatique industrielle
    Inscrit en
    Mai 2006
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Ing. R&D informatique industrielle
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 472
    Points : 221
    Points
    221
    Par défaut
    Merci de ton aide, ca me permet de regarder différemment.


    Si j'ai bien pigé, l'exemple que tu cites permets de créer un FileMapping à partir du fichier. Toi ce dont tu aurais besoin, c'est de créer un FileMapping sans fichier ?
    Oui c'est cela.

    Si j'ai bien compris :
    Pour permettre un partage entre 2 applications, il suffit donc d'avoir le même nom de mapping?

    Ensuite pour mettre la structure dans la mémoire, il suffit de faire pointer la structure sur la même adresse que le pointeur du mapping?

  4. #4
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Seine Maritime (Haute Normandie)

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Points : 578
    Points
    578
    Par défaut
    Hello

    Si j'ai bien compris :
    Pour permettre un partage entre 2 applications, il suffit donc d'avoir le même nom de mapping?
    Ouaip. Voir "Creating Named Shared Memory" dans MSDN, et bien sûr l'aide de CreateFileMapping.

    Ensuite pour mettre la structure dans la mémoire, il suffit de faire pointer la structure sur la même adresse que le pointeur du mapping?
    Reouaip. Voir pour ça "Reading and Writing From a File View" dans MSDN (google -> 1ère réponse)

    Tout ça c'est la première étape. Il faut ensuite penser à synchroniser les accès à la mémoire partagée depuis les 2 exe.
    Y'a un exemple en delphi qui peut t'inspirer: google "[WIN32]ECHANGE INTER-PROCESSUS VIA SHAREDMEMORY"

    <Une autre solution, c'est d'utiliser une DLL qui contient un segment de données partagé. google "Creating A Shared Memory Segment with C++Builder". L'article date de l'époque de Builder 4, mais ça fonctionne toujours avec Builder 6 et 2007, c'est ce que j'utilise.>

  5. #5
    Membre actif Avatar de Masmeta
    Homme Profil pro
    Ing. R&D informatique industrielle
    Inscrit en
    Mai 2006
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Ing. R&D informatique industrielle
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 472
    Points : 221
    Points
    221
    Par défaut
    J'ai fait 2 petites appli qui utilisent la mémoire partagé :
    1. Appli 1 contrôle un timer et affiche un compteur.
    2. Appli 2 a un timer et à chaque tick il incrémente un compteur.

    La mémoire partagé est composé d'un booléen validant l'utilisation du timer de l'appli2, et un entier avec la valeur de compteur. Ca marche bien. Je vais maintenant utiliser le principe de synchronisation avec le mutex
    D'après le code Delphi il faut utiliser un mutex avec événement.

    Voici l'algo que je pense mettre en place :
    Au démarrage appli :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Création de la mémoire partagé  ( createfilemapping) :
      récupération pointeur de la zone mémoire
      indique fin d'utilisation de la mémoire
    Création du mutex, et récupération du pointeur
    A la demande accès mémoire sur chaque appli
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Prendre possession du Mutex
     Recuperation pointeur  de la mémoire partagé
     Operation sur la structure partagée
     indique fin utilisation de la mémoire
    indique fin utilisation mutex
    evenement sur  R/W sur la mémoire.
    Je part sur cela ce matin, cependant je suis tout ouïe sur une meilleur solution .
    Encore merci de ton aide

  6. #6
    Membre actif Avatar de Masmeta
    Homme Profil pro
    Ing. R&D informatique industrielle
    Inscrit en
    Mai 2006
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Ing. R&D informatique industrielle
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 472
    Points : 221
    Points
    221
    Par défaut
    J'ai réussi l'implémentation du Mutex.
    Maintenant je bloque sur l'évènement du changement de valeur de la structure. Le but est simple si l'application 1 change la valeur d'une donnée de la structure, cela déclenche un évènement dans l'application 2.

    Pour l'instant, j'utilise un handle d'événement créer par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Handle hEvent = CreateEvent(NULL,TRUE,FALSE,"CptEvent"); //Creation evenement
    if (GetLastError() == ERROR_ALREADY_EXISTS )
    {
                    CloseHandle(hEvent);
    }
    Lors d'accès à ma mémoire partagée, je réalise un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     PulseEvent(hEvent);// déclenchement
    J'aimerai savoir si il est possible de l'attacher à un composant TNotifyEvent?

  7. #7
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Seine Maritime (Haute Normandie)

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Points : 578
    Points
    578
    Par défaut
    Directement, comme ça, je ne vois pas...

    Tu peux faire le WaitForSingleObjet(hEvent...) dans un thread tout simple. Quand l'Event est signalé, tu fais un Synchronize(<Fonction de la fenêtre principale>) pour interagir avec l'interface, le Thread reset l'Event et repart dans sa boucle.

  8. #8
    Membre actif Avatar de Masmeta
    Homme Profil pro
    Ing. R&D informatique industrielle
    Inscrit en
    Mai 2006
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Ing. R&D informatique industrielle
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 472
    Points : 221
    Points
    221
    Par défaut
    Je laisse tomber. Je vais rester pour l'instant avec des timers.
    Merci de ton aide

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 29/11/2011, 20h19
  2. Réponses: 2
    Dernier message: 14/10/2009, 10h36
  3. Utilisation de fichiers avec une structure
    Par showdown dans le forum C
    Réponses: 16
    Dernier message: 07/12/2006, 18h30
  4. Utilisation d'un template avec une map
    Par bonano dans le forum Langage
    Réponses: 6
    Dernier message: 09/08/2006, 21h26
  5. Probléme avec une structure
    Par astragoth dans le forum C++
    Réponses: 3
    Dernier message: 25/04/2006, 20h31

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