如何在.NET 中实现共享内存?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/439787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to implement shared memory in .NET?
提问by
I have a C++.NET app and a C#.NET app. I would like them to communicate via shared memory.
我有一个 C++.NET 应用程序和一个 C#.NET 应用程序。我希望他们通过共享内存进行通信。
How is it possible in .NET version 2.0 ?
在 .NET 2.0 版中怎么可能?
Mainly want to share a queue object.
主要是想共享一个队列对象。
回答by RandomNickName42
Update: Hey, here's a pageI just found with a compleate implmentation.
更新:嘿,这是我刚刚找到的一个带有完整实现的页面。
Using C++/CLI, it's quite easy to setup shared memory as per normal C++ API (C++/CLI being able to interact with the managed and native HEAP/memory references). The UnmanagedMemoryStream can then be used to expose a Stream object to C#.
使用 C++/CLI,按照普通 C++ API 设置共享内存非常容易(C++/CLI 能够与托管和本机 HEAP/内存引用交互)。然后可以使用 UnmanagedMemoryStream 将 Stream 对象公开给 C#。
I did not attach the .h file, but you can infer the layout of the pmapped native typedef fairly easially ;). You may also want to evaluate the possible use of a BufferedStream depending on your reader/writer use case. And the code is from a project which I do not use any more so I can not remember the status of it's bug regression.
我没有附上 .h 文件,但您可以很容易地推断出 pmapped 本机 typedef 的布局;)。您可能还想根据您的读写器用例评估 BufferedStream 的可能用途。代码来自一个我不再使用的项目,所以我不记得它的错误回归状态。
Here's the C++/CLI class which establishes a file mapping and exposes an UnmanagedMemoryStream;
这是建立文件映射并公开 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;
};
Here's CLoseMap at least... I just found it... it was not compiled with /CLR
至少这里是 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;
}
回答by Diadistis
There are several options for your applications to communicate. The most popular are Remoting and Pipes. There are several examples for both and before you choose one you should consider the pros and cons such as portability. Here are some useful 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
回答by Gant
Is shared memory the only option? There are many ways for two .NET processes to communicate. Some of them are:
共享内存是唯一的选择吗?两个 .NET 进程可以通过多种方式进行通信。他们之中有一些是:
- .NET Remoting Object - Allow objects to interact with each other across processes. There is a good code sample here
- Microsoft Message Queue (MSMQ) - A shared message queue between processes. MSMQ will run as another Windows Service.
- .NET Remoting Object - 允许对象跨进程相互交互。这是一个很好的代码示例在这里
- Microsoft 消息队列 (MSMQ) - 进程之间的共享消息队列。MSMQ 将作为另一个 Windows 服务运行。
回答by puikos
You also have an alternative to C++/CLI as importing win32 functions in your C# app:
您还可以在 C# 应用程序中导入 win32 函数来替代 C++/CLI:
[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);
回答by puikos
I suppose .NET v2.0 does not have in-built support for shared memory. At most we can PInvoke the CreateFileMapping and MapViewOfFile APIs.
我想 .NET v2.0 没有对共享内存的内置支持。我们最多可以调用 CreateFileMapping 和 MapViewOfFile API。
In my scenario the IPC must take place on a single machine. So pipes is the fastest option as of now.
在我的场景中,IPC 必须在一台机器上进行。所以管道是目前最快的选择。
Thanks for the answers
感谢您的回答
回答by Esay
Take a look at this [link]: http://www.albahari.com/nutshell/ch22.aspxin Shared memory wrapper you can find your answer.
看看这个[链接]:http: //www.albahari.com/nutshell/ch22.aspx在共享内存包装器中,您可以找到答案。

