views:

4525

answers:

4

I have a C++.NET app and a C#.NET app. I would like them to communicate via shared memory.

How is it possible in .NET version 2.0 ?

Mainly want to share a queue object.

+5  A: 

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

.NET Remoting with an easy example

Diadistis
It's a great answer and all but the question was about shared memory.
Rick Minerich
+1  A: 

Is shared memory the only option? There are many ways for two .NET processes to communicate. Some of them are:

  • .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.
m3rLinEz
+1  A: 

I suppose .NET v2.0 does not have in-built support for shared memory. At most we can PInvoke the CreateFileMapping and MapViewOfFile APIs.

In my scenario the IPC must take place on a single machine. So pipes is the fastest option as of now.

Thanks for the answers

+5  A: 

Update: Hey, here's a page I 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#.

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.

Here's the C++/CLI class which establishes a file mapping and exposes an UnmanagedMemoryStream;

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

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