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 :

Tableau de char à deux dimensions pour Memoire partagée


Sujet :

C++

  1. #1
    Membre habitué
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9
    Par défaut Tableau de char à deux dimensions pour Memoire partagée
    Bom dia pessoal!

    Je rencontre un problème avec l'utilisation de la mémoire partagée entre processus. J'ai réussi à faire un code qui marche pour un array de char en mémoire partagée (et je lui passe une dimension MSG_SIZE = 31). Le code qui marche est le suivant :

    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
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    #include <windows.h>
    #include <stdio.h>
    #include <pthread.h>
    #include <errno.h>
    #include <string.h>
     
    #define MSG_SIZE 31
    #define BUFFER_SIZE 300
     
    // THREAD PRIMARIA
    int main()
    {
     
    	int i;
    	int status;
    	bool bStatus;
    	DWORD dwThreadId;
    	HANDLE hRAM;
    	HANDLE hEventSent;
    	HANDLE hEventRead;
    	STARTUPINFO si;
    	PROCESS_INFORMATION NewProcess;
    	char Mensagem[] = "";
    	char *Image;
    	char PathBuf[BUFFER_SIZE];
    	char PathBuf2[BUFFER_SIZE];
     
    	SetConsoleTitle("CLP");
     
     
     
    	hRAM= CreateFileMapping(
    		(HANDLE)0xFFFFFFFF,
    		NULL,
    		PAGE_READWRITE,		// tipo de acesso
    		0,					// dwMaximumSizeHigh
    		MSG_SIZE,					// dwMaximumSizeLow
    		"LISTA_CIRCULAR");			// Escolha o seu nome preferido
     
    	Image= (char *)MapViewOfFile(
    		hRAM,
    		FILE_MAP_WRITE,		// Direitos de acesso: leitura e escrita
    		0,					// dwOffsetHigh
    		0,					// dwOffset Low
    		MSG_SIZE);			// Número de bytes a serem mapeados
     
    	// Cria evento com reset automático
    	hEventSent= CreateEvent(NULL, FALSE, FALSE,"MsgAvailable");
     
    	// Cria evento com reset automático
    	hEventRead= CreateEvent(NULL, FALSE, FALSE,"MsgRead");
     
    	// Cria processo servidor
    	ZeroMemory(&si, sizeof(si));
    	si.cb = sizeof(si);	// Tamanho da estrutura em bytes
     
     
    	if(!GetCurrentDirectory(BUFFER_SIZE, PathBuf))
    	printf("GetCurrentDirectory() failed!\n");
     
    	strcpy(PathBuf2, PathBuf);
    	strcat(PathBuf,"\\CapturaMensagens\\Debug\\CapturaMensagens.exe");
    	strcat(PathBuf2,"\\CapturaMensagens\\Debug");
     
    	ZeroMemory(&si,sizeof(si));
    	si.cb = sizeof(si);
     
    	bStatus = CreateProcessA(PathBuf, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, PathBuf2, &si, &NewProcess);
    	if (!bStatus) printf ("Erro na criacao do Processo! Codigo = %d\n", GetLastError());
     
     
    	do {
    		strcpy(Mensagem,"ESSAI");
     
    		// Escreve na memória compartilhada
    		strcpy(Image, Mensagem);	
    		SetEvent(hEventSent);	// Avisa processo B
     
    		// Espera que processo B leia a mensagem 
    		WaitForSingleObject(hEventRead, INFINITE); 
    		ResetEvent(hEventRead);
    		printf("Buffer apos leitura/limpeza [deve ser NULL]= %s\n\n", Image);
    	} while(TRUE);
     
    	// Elimina mapeamento
    	bStatus=UnmapViewOfFile(Image);
     
    	CloseHandle(hRAM);
    	CloseHandle(hEventSent);
    	CloseHandle(hEventRead);
    	CloseHandle(NewProcess.hProcess);
    	CloseHandle(NewProcess.hThread);
    }	// main

    Jusque là, tout va bien. Mais ce n'était qu'une étape pour arriver à mon objectif, passer un array de char à 2 dimensions N*M ( char **Image; ), avec N=200 et M=31 (comme avant). J'ai tenté beaucoup de choses, jusqu'à écrire très salement, et je n'arrive vraiment pas à trouver comment modifier mon code qui fonctionne avec char *Image pour qu'il fonctionne avec char**.

    Si vous avez une idée sur comment modifier CreateFileMapping et MapViewOfFile pour l'adapter à mon cas, je suis TRES intéressé! Dernière ligne droite de mon projet!

    Obrigado antecipadamente gente!

    Stochelo

  2. #2
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2007
    Messages : 10
    Par défaut
    Bonjour,

    Je ne réponds pas directement à ta question, mais pourquoi utiliser un tableau de pointeurs ?

    Ça ne me parait pas judicieux, tu vas perdre le bénéfice du près-fetcheur qui anticipe le chargement mémoire afin que tes processeurs ne passent pas leur temps à attendre des données. Il vaut mieux stocker tes données dans un tableau à une dimension de taille N*M et d'y accéder en calculant la coordonnée à une dimension (index) à partir de la coordonnée à deux dimensions (row, col) avec l'opération :
    Je pense que c'est pour la même raison que la bibliothèque que tu utilises ne fournit pas de fonction pour charger l'image dans un tableau de pointeurs.

  3. #3
    Membre habitué
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9
    Par défaut
    Merci pour la réponse! J'avais pensé à écrire une solution de ce genre, mais malheureusement mon professeur n'accepte pas cette forme-là! (et bien sûr ne donne pas d'indice sur comment résoudre ce problème! ). Je ne peux pas terminer mon programme sans cela, c'est lassant de ne pas trouver!

  4. #4
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Dans ce cas, discutes-en avec lui, vu que c'est la bonne solution.

    Explique-lui pourquoi c'est la bonne solution, et s'il est honnète, il devrait comprendre et accepter.

    Regarde dans la faq à cette entrée et cette autre.

  5. #5
    Membre habitué
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9
    Par défaut
    J'ai un début d'élément de réponse à ma question, et j'aimerais bien avoir votre avis pour tenter de résoudre ce problème qui m'empêche de dormir depuis 2 jours!

    Suivant la doc de MapViewOfFile:
    http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
    dwFileOffsetHigh doit toujours être 0 sur tous les sites que j'ai pu voir.
    dwFileOffsetLow est l'offset auquel on commence la "view de la map". Du coup, à chaque appel de ma fonction MapViewOfFile pour chaque position de mon tableau (200 positions), je dois ajouter un offset pour ne pas retourner un pointeur vers une même adresse en utilisant le même dwFileOffsetLow (=0) à chaque appel de la fonction.


    LE PROBLEME, est que sur tous les sites, ils disent d'utiliser Allocation Granularity pour utiliser un mulitple de ce dernier (65536) en tant qu'offset à chaque appel de MapViewOfFile. En terme de code, ça donnerait :

    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
    #include <windows.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    
    #define MSG_SIZE 31
    #define BUFFER_SIZE 300
    #define NUMERO_POSICAO 10
    
    int main()
    {
    
        int i;
        HANDLE hRAM;
        STARTUPINFO si;
        PROCESS_INFORMATION NewProcess;
        char Nome[] = "000";
        char **Image;
    
    
    i=0;
    
     //Allocation de la 1er dimension */
    Image = (char **)malloc (sizeof(char*)*NUMERO_POSICAO);
    SYSTEM_INFO info;
    GetSystemInfo(&info);
    
    DWORD bufferSize = info.dwAllocationGranularity;
    
     do {
            sprintf(Nome,"%003d",i);
            hRAM = CreateFileMapping(
                (HANDLE)0xFFFFFFFF,
                NULL,
                PAGE_READWRITE,        // tipo de acesso
                0,                    // dwMaximumSizeHigh
                MSG_SIZE,                    // dwMaximumSizeLow
                Nome);            // Escolha o seu nome preferido
            if (hRAM==NULL) printf ("Erro na criacao do FileMapping! Codigo = %d\n", GetLastError());
    
            Image[i] = (char *)MapViewOfFile(
                hRAM,
                FILE_MAP_WRITE,        // Direitos de acesso: leitura e escrita
                0,                    // dwOffsetHigh
                i*bufferSize,                    // dwOffset Low : OFFSET MULTIPLE
                MSG_SIZE);            // Número de bytes a serem mapeados
            if (Image[i]==NULL) printf ("Erro na criacao do MapView! Codigo = %d\n", GetLastError());
            i++;
        } while(i<NUMERO_POSICAO);
    }
    Pour i=0, pas de problèmes, mais dès que i>0, cela renvoie une erreur 5 (access denied apparemment). Malheureusement, ce que tous les sites préconisent (multiple d'allocation granularity) ne fonctionne pas, et je ne suis pas le seul à avoir ce problème sur le net.

    Quelqu'un peut me sauver???

Discussions similaires

  1. Construction d'un tableau de char à 2 dimensions
    Par mounir31400 dans le forum Débuter
    Réponses: 4
    Dernier message: 12/05/2015, 09h53
  2. Stocker une string dans un tableau de char à deux dimensions
    Par faitor1 dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 03/03/2014, 02h12
  3. Tableau à une ou deux dimensions:
    Par ghyosmik dans le forum Débuter
    Réponses: 2
    Dernier message: 10/01/2009, 13h47
  4. tableau dynamique de deux dimensions
    Par lecamer dans le forum VB 6 et antérieur
    Réponses: 10
    Dernier message: 31/07/2008, 15h36
  5. tableau qui a deux couleur pour les lignes <td>
    Par abdess6600 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 23/05/2006, 16h50

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