memtest - ¿Cómo implementar memoria compartida en.NET?
memoria compartida grafica (6)
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<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;
};
Aquí está CLoseMap al menos ... Acabo de encontrarlo ... no fue compilado 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;
}
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.
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);
¿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.
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
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.