【问题标题】:How to implement shared memory in .NET?如何在 .NET 中实现共享内存?
【发布时间】:2010-10-01 04:28:42
【问题描述】:

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

.NET 2.0 版怎么可能?

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

【问题讨论】:

    标签: .net shared-memory


    【解决方案1】:

    您的应用程序可以通过多种方式进行通信。最受欢迎的是远程处理和管道。两者都有几个示例,在您选择一个之前,您应该考虑其优缺点,例如可移植性。以下是一些有用的链接:

    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

    【讨论】:

    • 这是一个很好的答案,除了问题之外都是关于共享内存的。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

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

      感谢您的回答

      【讨论】:

        【解决方案4】:

        更新:嘿,here's a page 我刚刚发现了一个完整的实现。


        使用 C++/CLI,很容易按照普通 C++ API 设置共享内存(C++/CLI 能够与托管和本机 HEAP/内存引用进行交互)。然后可以使用 UnmanagedMemoryStream 将 Stream 对象公开给 C#。

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

        这是建立文件映射并公开 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;
        };
        

        至少这里是 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;
        }
        

        【讨论】:

        【解决方案5】:

        您还可以在 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);
        

        【讨论】:

          【解决方案6】:

          看看这个[链接]: http://www.albahari.com/nutshell/ch22.aspx 在共享内存包装器中,您可以找到答案。

          【讨论】:

            猜你喜欢
            • 2011-05-27
            • 2018-11-23
            • 1970-01-01
            • 2011-06-02
            • 2016-05-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多