2009-01-13 6 views

Répondre

6

Plusieurs applications peuvent communiquer entre elles. Les plus populaires sont Remoting et Pipes. Il y a plusieurs exemples pour les deux et avant de choisir un, vous devriez considérer les avantages et les inconvénients tels que la portabilité. Voici quelques liens utiles:

Inter-Process Communication in .NET Using Named Pipes, Part 1

Inter-Process Communication in .NET Using Named Pipes, Part 2

.NET Remoting in Simple English

.NET Remoting with an easy example

+4

C'est une excellente réponse et tout sauf la question était sur la mémoire partagée. –

3

est-mémoire partagée la seule option? Il y a plusieurs façons de communiquer entre deux processus .NET. Certains d'entre eux sont:

  • Objet .NET Remoting - Autoriser les objets à interagir entre eux à travers les processus. Il existe un bon exemple de code here
  • Microsoft Message Queue (MSMQ) - Une file d'attente de messages partagés entre les processus. MSMQ fonctionnera comme un autre service Windows.
1

Je suppose que .NET v2.0 n'a pas de support intégré pour la mémoire partagée. Au plus, nous pouvons PInvoquer les API CreateFileMapping et MapViewOfFile.

Dans mon scénario, l'IPC doit avoir lieu sur une seule machine. Donc, les tuyaux sont l'option la plus rapide à partir de maintenant.

Merci pour les réponses

13

Mise à jour: Hey, here's a page Je viens de découvrir un implmentation de compleate.


en C++/CLI, il est très facile à installer la mémoire partagée selon API normale C++ (pouvoir C++/CLI pour interagir avec les références HEAP/mémoire géré et natif). Le UnmanagedMemoryStream peut ensuite être utilisé pour exposer un objet Stream à C#.

Je n'ai pas attaché le fichier .h, mais vous pouvez inférer la mise en page de la typedef native pmpl assez facilement;). Vous pouvez également évaluer l'utilisation possible d'un BufferedStream en fonction de votre cas d'utilisation de lecteur/graveur. Et le code provient d'un projet que je n'utilise plus, je ne peux donc pas me souvenir de l'état de sa régression.

Voici la classe C++/CLI qui établit un mappage de fichiers et expose UnmanagedMemoryStream;

public ref class MemMapp 
{ 
    public: 
     __clrcall MemMapp(String^ file) 
     { 
      map = NULL; 

      if(!File::Exists(file)) throw gcnew ApplicationException("Can not find file " + file); 

      marshal_context^ x = gcnew marshal_context(); 
      const char *nname = x->marshal_as<const char*>(file); 

      map = (pmapped) malloc(sizeof(mapped)); 
      ZeroMemory(map, sizeof(mapped)); 
      map->name = strdup(nname); 
      InitMap(map); 
     } 
     void __clrcall MapBytes(long long loc, long length) 
     { 
      map->low = loc & 0xffffffff; 
      map->high = (loc >> 32) & 0xffffffff; 
      map->size = length & 0xffffffff; 
      if(!GetMapForFile(map)) 
       throw gcnew ApplicationException("can not map range " + loc + " :" + length); 

      if(map->size = 0) 
       map->size = MAXMAX&0xffffffff; 

     } 
     UnmanagedMemoryStream ^View() 
     { 
      return gcnew UnmanagedMemoryStream((unsigned char *) map->blok, map->size, map->size, FileAccess::Read); 
     } 
     long long __clrcall FileSize() 
     { 
      DWORD high, low; 
      long long rv; 

      low = GetFileSize(map->hFile, &high); 
      maxmax = high; 
      maxmax << 32; 
      maxmax += low; 

      rv = high; 
      rv << 32; 
      rv = rv & low; 
      return rv; 
     } 
     property unsigned int MinBufSiz { unsigned int get() { return map->dwbufz; } } 
     property long long BufBase { long long get() { return (map->high << 32) + map->low; } } 
     property long long BufLim { long long get() { return ((map->high << 32) + map->low) + map->size; } } 
     property long long MAXMAX { long long get() { return maxmax; } } 
     static MemMapp() { } 
     __clrcall ~MemMapp() { if(map != NULL) { CloseMap(map); free(map->name); free(map); map = NULL; } } 
    protected: 
     __clrcall !MemMapp() { if(map != NULL) { CloseMap(map); free(map->name); free(map); map = NULL; } } 
     pmapped map; 
     long long maxmax; 
}; 

Voilà CLoseMap au moins ... Je trouve juste ...il n'a pas été compilé avec/CLR


bool CloseMap(pmapped map) 
{ 
    if(map->blok != NULL) { 
     UnmapViewOfFile(map->blok); 
     map->blok = NULL; 
    } 
    if(map->hMap != INVALID_HANDLE_VALUE && map->hMap != NULL) { 
     CloseHandle(map->hMap); 
     map->hMap = INVALID_HANDLE_VALUE; 
    } 
    if(map->hFile != INVALID_HANDLE_VALUE && map->hFile != NULL) { 
     CloseHandle(map->hFile); 
     map->hFile = INVALID_HANDLE_VALUE; 
    } 
    return false; 
} 
+2

+1 .net 4 prend en charge les fichiers mappés en mémoire http://msdn.microsoft.com/fr-fr/library/system.io.memorymappedfiles.aspx – kenny

3

Vous avez également une alternative à C++/CLI comme l'importation des fonctions win32 dans votre C# app:

[DllImport ("kernel32.dll", SetLastError = true)] 
    static extern IntPtr CreateFileMapping (IntPtr hFile, 
              int lpAttributes, 
              FileProtection flProtect, 
              uint dwMaximumSizeHigh, 
              uint dwMaximumSizeLow, 
              string lpName); 

    [DllImport ("kernel32.dll", SetLastError=true)] 
    static extern IntPtr OpenFileMapping (FileRights dwDesiredAccess, 
             bool bInheritHandle, 
             string lpName); 

    [DllImport ("kernel32.dll", SetLastError = true)] 
    static extern IntPtr MapViewOfFile (IntPtr hFileMappingObject, 
             FileRights dwDesiredAccess, 
             uint dwFileOffsetHigh, 
             uint dwFileOffsetLow, 
             uint dwNumberOfBytesToMap); 
    [DllImport ("Kernel32.dll")] 
    static extern bool UnmapViewOfFile (IntPtr map); 

    [DllImport ("kernel32.dll")] 
    static extern int CloseHandle (IntPtr hObject); 
Questions connexes