2009-01-13 7 views

Antwort

6

Es gibt mehrere Möglichkeiten für die Kommunikation Ihrer Anwendungen. Am beliebtesten sind Remoting und Pipes. Es gibt mehrere Beispiele für beide und bevor Sie sich entscheiden, sollten Sie die Vor- und Nachteile wie Portabilität berücksichtigen. Hier sind einige nützliche Links:

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

Es ist eine gute Antwort und alles, aber die Frage war über Shared Memory. –

3

Ist Shared Memory die einzige Option? Es gibt viele Möglichkeiten für die Kommunikation von zwei .NET-Prozessen. Einige davon sind:

  • .NET Remoting-Objekt - ermöglichen Objekte interagieren über Prozesse hinweg. Es gibt ein gutes Codebeispiel here
  • Microsoft Message Queue (MSMQ) - eine gemeinsame Nachrichtenwarteschlange zwischen Prozessen. MSMQ wird als ein anderer Windows-Dienst ausgeführt.
1

Ich nehme an, dass .NET v2.0 keine eingebaute Unterstützung für Shared Memory hat. Allenfalls können wir die APIs CreateFileMapping und MapViewOfFile aufrufen.

In meinem Szenario muss der IPC auf einer einzigen Maschine stattfinden. So ist Pipes ab sofort die schnellste Option.

Danke für die Antworten

13

Update: Hey, here's a page ich mit einem Komplettrad implmentation gerade gefunden.


Verwendung von C++/CLI, es ganz einfach ist die Einrichtung gemeinsam genutzten Speicher wie für normalen C++ API (C++/CLI der Lage, mit den verwalteten und nativen HEAP/Speicherreferenzen zu interagieren). Der UnmanagedMemoryStream kann dann verwendet werden, um ein Stream-Objekt für C# verfügbar zu machen.

Ich habe die .h-Datei nicht angehängt, aber Sie können das Layout des pmapped nativen Typedef ziemlich leicht ableiten;). Vielleicht möchten Sie auch die mögliche Verwendung eines BufferedStream abhängig von Ihrem Leser/Schreiber-Anwendungsfall bewerten. Und der Code stammt von einem Projekt, das ich nicht mehr verwende, so dass ich mich nicht mehr an den Status der Bugregression erinnern kann.

Hier ist die C++/CLI-Klasse, die eine Dateizuordnung herstellt und einen UnmanagedMemoryStream darstellt;

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; 
}; 

Hier CLoseMap mindestens ... Ich kann es nur gefunden ...es wurde nicht mit/CLR


zusammengestellt
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 unterstützt Speicherabbilddateien http://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.aspx – kenny

3

Sie auch eine Alternative zu C++/CLI haben als win32 Funktionen in C# app importieren:

[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); 
Verwandte Themen