18

C++.NET アプリと C#.NET アプリがあります。共有メモリを介して通信したいと思います。

.NET バージョン 2.0 ではどのように可能ですか?

主にキュー オブジェクトを共有したい。

4

6 に答える 6

14

更新: ねえ、これは私がちょうど完全な実装で見つけたページです。


C++/CLI を使用すると、通常の C++ API に従って共有メモリを簡単にセットアップできます (C++/CLI はマネージドおよびネイティブの HEAP/メモリ参照と対話できます)。UnmanagedMemoryStream を使用して、Stream オブジェクトを C# に公開できます。

.h ファイルは添付しませんでしたが、pmap されたネイティブ 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;
}
于 2009-05-29T10:01:38.873 に答える
6

アプリケーションが通信するためのオプションがいくつかあります。最も人気があるのは、Remoting と Pipes です。どちらにもいくつかの例があり、いずれかを選択する前に、移植性などの長所と短所を考慮する必要があります。便利なリンクを次に示します。

名前付きパイプを使用した .NET でのプロセス間通信、パート 1

名前付きパイプを使用した .NET でのプロセス間通信、パート 2

簡単な英語での .NET リモート処理

簡単な例による .NET リモート処理

于 2009-01-13T17:10:02.487 に答える
3

共有メモリは唯一のオプションですか? 2 つの .NET プロセスが通信する方法は多数あります。それらのいくつかは次のとおりです。

  • .NET Remoting Object - オブジェクトがプロセス間で相互に対話できるようにします。ここに良いコードサンプルがあります
  • Microsoft Message Queue (MSMQ) - プロセス間の共有メッセージ キュー。MSMQ は別の Windows サービスとして実行されます。
于 2009-01-13T17:11:04.700 に答える
3

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);
于 2011-12-12T11:58:28.013 に答える
1

.NET v2.0 には、共有メモリのサポートが組み込まれていないと思います。せいぜい、CreateFileMapping API と MapViewOfFile API を PInvoke できます。

私のシナリオでは、IPC は 1 台のマシンで実行する必要があります。したがって、現時点ではパイプが最速のオプションです。

答えてくれてありがとう

于 2009-01-13T18:31:14.337 に答える
0

この [リンク] を見てみましょう: http://www.albahari.com/nutshell/ch22.aspx in Shared memory wrapper で答えを見つけることができます。

于 2016-07-12T08:16:12.733 に答える