如何在.NET中实现共享内存? 我有一个C++ .NET应用程序和一个C .net .NET应用程序。我希望他们通过共享内存进行通信

如何在.NET中实现共享内存? 我有一个C++ .NET应用程序和一个C .net .NET应用程序。我希望他们通过共享内存进行通信,.net,shared-memory,.net,Shared Memory,在.NET 2.0版中如何实现这一点 主要希望共享队列对象。应用程序有几个通信选项。最流行的是远程处理和管道。有两个例子,在你选择一个之前,你应该考虑利弊,比如便携性。以下是一些有用的链接: 共享内存是唯一的选择吗?两个.NET进程的通信方式有很多种。其中包括: .NET远程处理对象-允许对象跨进程相互交互。有一个很好的代码示例 Microsoft消息队列(MSMQ)-进程之间的共享消息队列。MSMQ将作为另一个Windows服务运行 我想.NET v2.0没有内置的共享内存支持。 我们

在.NET 2.0版中如何实现这一点


主要希望共享队列对象。

应用程序有几个通信选项。最流行的是远程处理和管道。有两个例子,在你选择一个之前,你应该考虑利弊,比如便携性。以下是一些有用的链接:


共享内存是唯一的选择吗?两个.NET进程的通信方式有很多种。其中包括:

  • .NET远程处理对象-允许对象跨进程相互交互。有一个很好的代码示例
  • Microsoft消息队列(MSMQ)-进程之间的共享消息队列。MSMQ将作为另一个Windows服务运行

    • 我想.NET v2.0没有内置的共享内存支持。 我们最多可以PInvoke CreateFileMapping和MapViewOffileAPI

      在我的场景中,IPC必须在一台机器上进行。因此,管道是目前最快的选择

      谢谢你的回答更新:嘿,我刚刚发现了一个完整的实现


      使用C++ C++/CLI,很容易根据普通的C++ API(C++/CLI能够与托管的和本地堆/内存引用进行交互)来设置共享内存。然后可以使用UnmanagedMemoryStream向C#公开流对象

      我没有附加.h文件,但您可以相当容易地推断出pmap本机typedef的布局;)。根据您的读写器用例,您可能还需要评估BufferedStream的可能用途。代码来自一个我不再使用的项目,所以我记不起它的bug回归状态

      下面是C++/CLI类,它建立了一个文件映射并公开了一个非托管的MemoryStream

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

      在C++应用程序中导入win32函数时,您还可以选择C++/CLI:


      看看这个[链接]:
      在共享内存包装器中,您可以找到您的答案。

      这是一个很好的答案,除了问题外,其他都是关于共享内存的。+1.net 4支持内存映射文件
      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;
      }
      
      [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);