¿Cómo implementar memoria compartida en .NET?

Tengo una aplicación C ++ .NET y una aplicación C # .NET. Me gustaría que se comuniquen a través de la memoria compartida.

¿Cómo es posible en .NET versión 2.0?

Principalmente quiero compartir un objeto de cola.

    Actualización: Oye, aquí hay una página que acabo de encontrar con una implementación completa.


    Al usar C ++ / CLI, es bastante fácil configurar la memoria compartida según la API normal de C ++ (C ++ / CLI puede interactuar con las referencias HEAP / memoria administradas y nativas). El UnmanagedMemoryStream se puede usar para exponer un objeto Stream a C #.

    No adjunté el archivo .h, pero puede inferir el diseño del tipo de letra nativo pmapped bastante fácilmente;). También es posible que desee evaluar el posible uso de un BufferedStream en función de su caso de uso de lector / escritor. Y el código es de un proyecto que ya no uso, así que no puedo recordar el estado de la regresión de errores.

    Aquí está la clase C ++ / CLI que establece una asignación de archivos y expone un 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(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; }; 

    Aquí está CLoseMap al menos … Acabo de encontrarlo … no fue comstackdo con / 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; } 

    Hay varias opciones para que sus aplicaciones se comuniquen. Los más populares son Remoting y Pipes. Hay varios ejemplos para ambos y, antes de elegir uno, debe considerar los pros y los contras, como la portabilidad. Aquí hay algunos enlaces útiles:

    Comunicación entre procesos en .NET utilizando canalizaciones con nombre, parte 1

    Comunicación entre procesos en .NET utilizando canalizaciones con nombre, parte 2

    .NET Remoting en inglés simple

    .NET Remoting con un ejemplo fácil

    ¿La memoria compartida es la única opción? Hay muchas maneras para comunicarse con dos procesos .NET. Algunos de ellos son:

    • Objeto Remoto .NET – Permitir que los objetos interactúen entre ellos en todos los procesos. Hay una buena muestra de código aquí
    • Microsoft Message Queue (MSMQ): una cola de mensajes compartidos entre procesos. MSMQ se ejecutará como otro servicio de Windows.

    También tiene una alternativa a C ++ / CLI para importar funciones win32 en su aplicación C #:

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

    Supongo que .NET v2.0 no tiene soporte incorporado para la memoria compartida. Como máximo, podemos invocar las API CreateFileMapping y MapViewOfFile.

    En mi escenario, el IPC debe tener lugar en una sola máquina. Entonces, las tuberías son la opción más rápida a partir de ahora.

    Gracias por las respuestas

    Eche un vistazo a este [enlace]: http://www.albahari.com/nutshell/ch22.aspx en Contenedor de memoria compartida puede encontrar su respuesta.