Mémoire partagée pour programme Windows

Mémoire partagée pour programme Windows - C++ - Programmation

Marsh Posté le 03-06-2009 à 15:39:38    

Bonjour tout le monde,  
 
Je dois faire communiquer deux programmes ( en c++) et j'ai choisi pour cela la mémoire partagée (windows only).
Après quelques recherches, je me suis mis à essayer d'adapter le code exemple de la msdn:
http://msdn.microsoft.com/en-us/li [...] S.85).aspx
 
Mon principal souci sont ces _t intempestifs dont je ne comprend pas la signification. (Cela servirait pour faire en format Unicode, mais encore?), cela ne m'aide pas à essayer d'utiliser la fonction CopyMemory():
 
En effet CopyMemory ne reçoit que des types tchar const (tchar?) or je voudrai envoyer des tableaux d'entiers, des chaines et des structures).  
(j'ai essayer de faire des casts mais il y a des violations mémoire au pire, le contenu est illisible par un programme tiers au mieux.)
Bref je ne sais pas si mon approche est la bonne ou si il y a éventuellement d'autres moyens auxquels je n'ai pas pensé.
en vous remerciant d'avance!


Message édité par Vings le 03-06-2009 à 15:48:53

---------------
"Il faut avoir bien du jugement pour sentir que nous n'en avons point."  
Reply

Marsh Posté le 03-06-2009 à 15:39:38   

Reply

Marsh Posté le 03-06-2009 à 15:54:40    

Pour ton problème d'utilisation de ta mémoire partagée, poste ton code.
Y'a que comme ça qu'on pourra t'aider a refactoriser tes échanges de données entre process.

 

----

 

Après pour l'aspect gestion des mémoires partagées, je te conseillerai comme d'habitude ici boost.

 

boost::interprocess::windows_shared_memory, si tu veux une gestion de la vie de la mémoire partagée à la Windows (plus de handles => l'os delete la mémoire partagée)

 

Le portage sera toujours plus facile sous un autre OS par la suite.

 


Message édité par bjone le 03-06-2009 à 15:58:05
Reply

Marsh Posté le 03-06-2009 à 16:35:21    

Merci de ton intervention,
 je n'ai pas posté mon code car il est une quasi reproduction de la msdn (je fais une programme test avant de l'implémenter); Néanmoins voilà le code issue du lien posté plus haut:
 
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
 
#define BUF_SIZE 256
TCHAR szName[]=TEXT("Global\\MyFileMappingObject" );
TCHAR szMsg[]=TEXT("Message from first process." );
 
int _tmain()
{
   HANDLE hMapFile;
   LPCTSTR pBuf;
 
   hMapFile = CreateFileMapping(
                 INVALID_HANDLE_VALUE,    // use paging file
                 NULL,                    // default security  
                 PAGE_READWRITE,          // read/write access
                 0,                       // max. object size  
                 BUF_SIZE,                // buffer size  
                 szName);                 // name of mapping object
 
   if (hMapFile == NULL)  
   {  
      _tprintf(TEXT("Could not create file mapping object (%d).\n" ),  
             GetLastError());
      return 1;
   }
   pBuf = (LPTSTR) MapViewOfFile(hMapFile,   // handle to map object
                        FILE_MAP_ALL_ACCESS, // read/write permission
                        0,                    
                        0,                    
                        BUF_SIZE);            
 
   if (pBuf == NULL)  
   {  
      _tprintf(TEXT("Could not map view of file (%d).\n" ),  
             GetLastError());  
 
    CloseHandle(hMapFile);
 
      return 1;
   }
 
   
   CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
    _getch();
 
   UnmapViewOfFile(pBuf);
 
   CloseHandle(hMapFile);
 
   return 0;
}
 
Ca marche bien avec le programme client mais je voudrai adapter cette fonction:
CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
  //  _getch();
 
pour qu'au lieu de szMsg (qui est un tableau static w_chart) je puisse mettre une structure, ou des entiers.

Reply

Marsh Posté le 03-06-2009 à 16:49:23    

Tu as deux étapes: déjà avoir une idée de ce que tu vas devoir passer en termes de volumes, pour savoir quelle dimension donner à ta mémoire partagée.
 
Ensuite bah il y a plusieures manières de voir le passage de données, ça peut être vu comme un problème de sérialisation, comme tu peux gruger en faisant des assignements via des casts si tes types/classes sont triviaux. Toutes les solutions sont possibles :D
 
Pour trancher c'est le reste du code, et ce que tu veux y mettre qu'il faut avoir.
 
Donc décrits tes types et l'utilisation que tu comptes avoir de la mémoire partagée.


Message édité par bjone le 03-06-2009 à 17:06:17
Reply

Marsh Posté le 03-06-2009 à 17:22:31    

Ce que je compte faire passer en mémoire partagée ce sont 3 tableaux alloués dynamiquement: l'un d'entier, l'autre de booléens, le dernier de chaines de caractères.  
 
Initialement, j'avais une dll avec des variables partagées dessus, c'était très simple et ça marchait, seulement on ne pouvait y mettre de pointeur (car sinon le contenu des pointeur étaient en dehors de la zone de mémoire)  :fou: , donc j'ai jeté mon dévolu sur la mémoire partagée mais je me demande si c'est vraiment performant: quand je vois les fonctions nécessaire pour convertir un entier en w_chart  j'imagine pas l'appliquer pour tout mon programme.  :ouch:


---------------
"Il faut avoir bien du jugement pour sentir que nous n'en avons point."  
Reply

Marsh Posté le 03-06-2009 à 17:24:17    

t'as benché avant de dire ça :o Punaise, la tonne de premature optimizer ces temps çi :/

Reply

Marsh Posté le 03-06-2009 à 20:32:45    

Sur quel critère se basé pour savoir si  on a une premature optimizer

Reply

Marsh Posté le 03-06-2009 à 21:20:30    

? je comprend pas ce que vous dites!

Reply

Marsh Posté le 03-06-2009 à 21:57:34    

Glock 17Pro a écrit :

Sur quel critère se basé pour savoir si  on a une premature optimizer


vouloir optimisé des bribes de code sans avoir fait de profiling en se basant a l'instainct.
C'ets la pire des choses à faire.

Reply

Marsh Posté le 03-06-2009 à 22:03:25    

Vings a écrit :

Ce que je compte faire passer en mémoire partagée ce sont 3 tableaux alloués dynamiquement: l'un d'entier, l'autre de booléens, le dernier de chaines de caractères.  
 
Initialement, j'avais une dll avec des variables partagées dessus, c'était très simple et ça marchait, seulement on ne pouvait y mettre de pointeur (car sinon le contenu des pointeur étaient en dehors de la zone de mémoire)  :fou: , donc j'ai jeté mon dévolu sur la mémoire partagée mais je me demande si c'est vraiment performant: quand je vois les fonctions nécessaire pour convertir un entier en w_chart j'imagine pas l'appliquer pour tout mon programme.  :ouch:


 
Qué ?
 
Une mémoire partagée est une mémoire partagée. Y'a rien à convertir, tu peux pas avoir plus rapide comme accès partagé a des données.


Message édité par bjone le 03-06-2009 à 22:04:56
Reply

Marsh Posté le 03-06-2009 à 22:03:25   

Reply

Marsh Posté le 03-06-2009 à 22:04:44    

Joel F a écrit :


vouloir optimisé des bribes de code sans avoir fait de profiling en se basant a l'instainct.
C'ets la pire des choses à faire.


 
Le problème n'est pas là, le problème est que Vings ne sait pas ce qu'il veut faire.

Reply

Marsh Posté le 04-06-2009 à 06:55:35    

bjone a écrit :


 
Le problème n'est pas là, le problème est que Vings ne sait pas ce qu'il veut faire.


 
je parlais de ça remarque sur le temps d'exécution

Reply

Marsh Posté le 04-06-2009 à 11:14:15    

Y a t'il moyen de revenir à mon problème premier? Je demande pas mieux d'utiliser la mémoire partagée, mais j'ai comme vous avez pu le remarquer je suis un débutant en la  matière.
Mon problème se situe au niveau de la fonction CopyMemory(), je me suis mal exprimé d'ailleurs à ce propos, je ne voulais pas tant parler de performance que du caractère laborieux de son emploi (enfin pour le peu que j'en ai vu, et je n'y connais pour ainsi dire rien). J'essaie en vain d'adapter le code de la MSDN pour envoyer autre chose qu'une chaine de caractère constante, la serialisation est en effet une piste, mais je ne vois pas comment la réaliser.
 
Avez vous un lien sur un tutorial par exemple? ça m'aiderait grandement! Car je crois être passé à côté des fondamentaux.  
merci d'avance!


Message édité par Vings le 04-06-2009 à 12:02:02

---------------
"Il faut avoir bien du jugement pour sentir que nous n'en avons point."  
Reply

Marsh Posté le 04-06-2009 à 12:33:26    

http://www.google.fr/search?hl=fr& [...] 9e&spell=1
 
:D
 
Ce qu'il faut c'est que tu vois des exemples d'échanges à travers une mémoire partagée.
 
Mais y'a rien de spécial, au final c'est un espace comme un bloc mémoire alloué par un malloc() , donc à toir de voir comment la remplir....

Message cité 1 fois
Message édité par bjone le 04-06-2009 à 12:34:20
Reply

Marsh Posté le 04-06-2009 à 13:45:07    

bjone a écrit :

http://www.google.fr/search?hl=fr& [...] 9e&spell=1
 
:D
 
Ce qu'il faut c'est que tu vois des exemples d'échanges à travers une mémoire partagée.
 
Mais y'a rien de spécial, au final c'est un espace comme un bloc mémoire alloué par un malloc() , donc à toir de voir comment la remplir....


 
Merci mais j'ai bien cherché sur le net et je ne trouve rien de probant depuis 3 jours, en tout cas pour la manière que je cherche  :??:  
En effet, j'aurai bien voulu adapter l'exemple de la msdn, car ça me semble plus facile de le marshaller pour une application c#. C'est ça qui me semble bizarre: ne pas pouvoir adapter cet exemple. Enfin bon je vais continuer à chercher et tester, ça finira bien par s'éclaircir.  
Dans tous les cas merci de vos interventions.

Reply

Marsh Posté le 04-06-2009 à 14:26:11    

C# != C++ aussi.
Regarde boost::interprocess et ca sera plus simple je pense

Reply

Marsh Posté le 04-06-2009 à 16:30:10    

Vings a écrit :


 
Merci mais j'ai bien cherché sur le net et je ne trouve rien de probant depuis 3 jours, en tout cas pour la manière que je cherche  :??:  
En effet, j'aurai bien voulu adapter l'exemple de la msdn, car ça me semble plus facile de le marshaller pour une application c#. C'est ça qui me semble bizarre: ne pas pouvoir adapter cet exemple. Enfin bon je vais continuer à chercher et tester, ça finira bien par s'éclaircir.  
Dans tous les cas merci de vos interventions.


 
Y'a rien à faire. Une création de mémoire partagée reviens à une allocation. A toi de déposer et d'aller chercher ce dont tu as besoin...
Si tu as juste à synchroniser quelques états, tu as fais ta structure, tu crées ta mémoire partagée et tu maintiens un pointeur de structure sur la mémoire partagée et basta....
T'as besoin de pousser un volume variable, tu crées une mémoire partagée qui tiens ta structure d'état et de la marge pour tenir une certaine quantitée de données, et tu fais ton petit mécanisme de producteur/consommateur synchronisé par sémaphore ou mutex (ou peut-être rien).
 
Enfin c'est presque comme un malloc(), à toi de savoir combien tu as besoin, et ce que tu vas en faire.
 

Reply

Marsh Posté le 19-06-2009 à 12:00:24    

Bon j'ai choisi de faire du filemapping, je n'aurai pas de problème particulier si je n'avai pas à l'utiliser à partir d'une interface en c#.
Pour ce faire, je recycle ma dll en c++ qui sert de support aux fonction destiner à manipuler la mémoire partagée, mais j'ai un problème pour lire les données.
 
En effet il me faut marshaller la structure de donnée et il apparait que je me débrouille mal (exception Safe Array type Missmatch).
 
Voila le code
 

Code :
  1. ~~~~~~~~~~~~DLL CODE
  2. .h
  3. typedef struct DATAS
  4. {
  5.         int * tabINT;
  6.         bool * tabBOOL;
  7.         string *tabCHAR;
  8. }t_DATA;
  9. extern "C"
  10. {
  11. __declspec(dllexport) extern  t_COMPUTDATA *Cdata;
  12. __declspec(dllexport) extern  HANDLE hExchangeRW;
  13. __declspec(dllexport) extern  char*     exchangeSpaceRW;
  14.        
  15. __declspec(dllexport) extern  t_COMPUTDATA *getStructureDataTest();
  16. }
  17. .cpp
  18.   t_COMPUTDATA *getStructureDataTest()
  19. {
  20.          t_COMPUTDATA *data = new t_DATA;
  21.                
  22.                 data->tabINT= new int[size_set_datas];
  23.                 data->tabBOOL= new bool[size_set_commands];
  24.                 data->tabCHAR= new string[size_set_errors];
  25.                 data->tabINT[0] = 12;
  26.                 data->tabINT[1] = 12;
  27.                 data->tabINT[2] = 222;;
  28.                 data->tabBOOL[0]=true;
  29.                 data->tabBOOL[1]=false;
  30.                 data->tabBOOL[2]=true;
  31.                 data->tabCHAR[0]="Hello World";
  32.                 return(data);
  33. }
  34. ~~~~~~~~~~~~~C# Program
  35. namespace WindowsFormsApplication1
  36. {
  37.     [StructLayout(LayoutKind.Sequential)]
  38.     public class FData
  39.     {
  40.         public Int32[] tabINT;
  41.         public Int32[] tabBOOL;
  42.         [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = (int)ERROR.SIZE_SET_ERRORS)]
  43.         public IntPtr[] tabCHAR;
  44.         public FData()
  45.         {
  46.             tabINT = new Int32[(int)DATA.SIZE_SET_DATAS];
  47.             tabBOOL = new Int32[(int)COMMAND.SIZE_SET_COMMANDS];
  48.             tabCHAR = new IntPtr[(int)ERROR.SIZE_SET_ERRORS];
  49.         }
  50.        public void sreenFDatas()
  51.         {
  52.             Console.WriteLine("FData" );
  53.             Console.WriteLine("FData.tabINT" );
  54.             Console.WriteLine(tabINT[0]);
  55.             Console.WriteLine(tabINT[1]);
  56.             Console.WriteLine(tabINT[2]);
  57.         }
  58.     }
  59. }
  60.     public partial class FormControl : Form
  61.     {
  62.         [DllImport("InterfaceDLLMK4.dll", EntryPoint = "getStructureDataTest", CallingConvention = CallingConvention.Cdecl)]
  63.         static extern IntPtr getStructureDataTest();
  64.         public FormControl(ClassManager classManager)
  65.         {
  66.             AttachConsole(ATTACH_PARENT_PROCESS);
  67.             InitializeComponent();
  68.          
  69.            
  70.             setSpecifications((int)DATA.SIZE_SET_DATAS, (int)COMMAND.SIZE_SET_COMMANDS, (int)ERROR.SIZE_SET_ERRORS, (int)SIZE_BUFFER);
  71.             AllocSharedMemory();
  72.             fData = new FData();
  73.             IntPtr DataT = getStructureDataTest();
  74.             Marshal.PtrToStructure(DataT, fData); //[spoiler]SafeArrayTypeMismatchException
  75.             fData.sreenFDatas();
  76.             this.classManager = classManager;
  77.             this.init_Timer();
  78.         }
  79.         }


 
Si vous avez des idées...


Message édité par Vings le 23-07-2009 à 11:25:23

---------------
"Il faut avoir bien du jugement pour sentir que nous n'en avons point."  
Reply

Marsh Posté le 19-06-2009 à 14:01:16    

up! :bounce:

Reply

Marsh Posté le 19-06-2009 à 15:44:09    

:bounce:

Reply

Marsh Posté le 23-06-2009 à 10:14:47    

up! :bounce:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed