如何在.NET中实现共享内存?

我有一个C ++ .NET应用程序和一个C#.NET应用程序。 我希望他们通过共享内存进行通信。

如何在.NET 2.0版本中可能?

主要是想共享一个队列对象。

更新:嘿, 这是我刚刚find一个完整的实践的页面 。


使用C ++ / CLI,按照普通的C ++ API(C ++ / CLI能够与托pipe和原生HEAP /内存引用进行交互)来设置共享内存是相当容易的。 UnmanagedMemoryStream然后可以被用来暴露一个Stream对象到C#。

我没有附加.h文件,但可以相当简单地推断pmapped本机typedef的布局;)。 您可能还想根据您的读者/写者用例来评估BufferedStream的可能用途。 而代码来自一个我不再使用的项目,所以我不记得它的错误回归的状态。

这是build立文件映射并公开UnmanagedMemoryStream的C ++ / CLI类;

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

这里至less是CLoseMap …我刚刚发现它…它不是用/ 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; } 

有几个选项可供您的应用程序进行通信。 最受欢迎的是Remoting和Pipes。 有两个例子,在你select一个之前,你应该考虑如可移植性的利弊。 这里有一些有用的链接:

.NET中使用命名pipe道的进程间通信,第1部分

.NET中使用命名pipe道的进程间通信,第2部分

.NET Remoting使用简单的英文

NET Remoting与一个简单的例子

共享内存是唯一的select? 两个.NET进程可以通过多种方式进行通信。 其中一些是:

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

您还可以selectC ++ / CLI作为导入C#应用程序中的win32函数:

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

我想.NET 2.0没有共享内存的内置支持。 我们至多可以调用CreateFileMapping和MapViewOfFile API。

在我的情况下,IPC必须在一台机器上进行。 所以pipe道是目前最快的select。

感谢您的答案

看看这个[链接]: http : //www.albahari.com/nutshell/ch22.aspx共享内存包装,你可以find你的答案。