Torna al Thread

enum AllocationType { MEM_COMMIT = 0x1000, MEM_RESERVE = 0x2000, MEM_RESET = 0x8000 } enum DeallocationType { MEM_RELEASE = 0x8000 } enum MemoryProtection { PAGE_READONLY = 0x02, PAGE_READWRITE = 0x04 } [DllImport("kernel32.dll")] static extern IntPtr VirtualAlloc(IntPtr lpAddress, int dwSize, AllocationType fAllocationType, MemoryProtection flProtect); [DllImport("kernel32.dll")] static extern bool VirtualFree(IntPtr lpAddress, int dwSize, DeallocationType dwFreeType); struct SharedData { public int v1; public bool v2; public char v3; public Point v4; //Non puoi inserire delle variabili di tipo classe //perchè sono dei tipi di riferimento, e non //hanno senso nella memoria esterna } //Il contenuto di questo puntatore indica la necessità //di aggiornare i dati inseriti da un processo esterno unsafe bool* mustRefresh = null; //Questo è l'indirizzo della memoria dove scrivere i dati correnti IntPtr sharedMemPtr = IntPtr.Zero; //Questo è l'indirizzo della memoria dove gli altri processi scrivono //i nuovi dati per eseguire l'aggiornamento di quelli correnti IntPtr refreshPtr = IntPtr.Zero; //questi sono i dati che vengono elaborati da questo processo int data1; bool data2; char data3; Point data4; //Questa è la struttura che viene usata per scrivere e leggere i //dati sulla e dalla memoria condivisa SharedData data; //Questa funzione inizializza la memoria condivisa unsafe IntPtr InitSharedMem() { //Ottiene il numero di byte necessari a contenere la struttura //dei dati condivisi int byteCount = Marshal.SizeOf(typeof(SharedData)); //Alloca della memoria con accesso sia in lettura che in scrittura, //di dimensioni sufficienti a contenere i dati significativi sharedMemPtr = VirtualAlloc(IntPtr.Zero, //Il sistema sceglie l'indirizzo di allocazione byteCount, //Il numero di byte da allocare AllocationType.MEM_RESERVE | AllocationType.MEM_COMMIT, //riserva la memoria e la alloca MemoryProtection.PAGE_READWRITE); //permette la lettura e la scrittura //Alloca un bool nella memoria condivisa che viene usato per indicare //se l'applicazione deve aggiornare i dati mustRefresh = (bool*)VirtualAlloc(IntPtr.Zero, sizeof(bool), AllocationType.MEM_RESERVE | AllocationType.MEM_COMMIT, MemoryProtection.PAGE_READWRITE).ToPointer(); *mustRefresh = false; //Alloca della memoria con accesso in lettura e in scrittura, //che viene usata per ricevere i nuovi parametri per l'aggiornamento refreshPtr = VirtualAlloc(IntPtr.Zero, byteCount, AllocationType.MEM_COMMIT | AllocationType.MEM_RESERVE, MemoryProtection.PAGE_READWRITE); //Crea una chiave di registro dove scrivere l'indirizzo della memoria condivisa //e l'ID del processo da cui leggerla, serve alle applicazioni esterne per interagire RegistryKey swKey = Registry.LocalMachine.CreateSubKey("Software"); RegistryKey infoKey = swKey.CreateSubKey("SharedMemTest"); infoKey.SetValue("MemPtr", (int)sharedMemPtr, RegistryValueKind.DWord); infoKey.SetValue("ProcessID", Process.GetCurrentProcess().Id, RegistryValueKind.DWord); //Scrive nel registro l'indirizzo in memoria del valore da impostare //Per richiedere l'aggiornamento dei dati infoKey.SetValue("MustRefreshPtr", (int)mustRefresh, RegistryValueKind.DWord); //Scrive nel registro l'indirizzo della memoria condivisa dove inserire //i nuovi dati per il refresh infoKey.SetValue("NewDataPtr", (int)refreshPtr); //Chiude le chiavi di registro infoKey.Close(); swKey.Close(); //Ottiene l'indirizzo della memoria condivisa return sharedMemPtr; } //Questa funzione elabora i dati correnti void Elabora() { //Controlla se i dati devono essere aggiornati unsafe { if (*this.mustRefresh) { //Se sì, esegue l'aggiornamento: ottiene i nuovi dati dalla memoria condivisa this.data = (SharedData)Marshal.PtrToStructure(this.refreshPtr, typeof(SharedData)); //Aggiorna tutti i valori this.data1 = data.v1; this.data2 = data.v2; this.data3 = data.v3; this.data4 = data.v4; //Non è più necessario eseguire l'aggiornamento *mustRefresh = false; } } //Elabora i valori this.data1 += this.data4.X; this.data2 = !this.data2; this.data3 = (char)(data4.Y & 0xFF); this.data4.X++; this.data4.Y++; //Imposta i valori elaborati nella struttura this.data.v1 = data1; this.data.v2 = data2; this.data.v3 = data3; this.data.v4 = data4; //Scrive i valori nella memoria condivisa Marshal.StructureToPtr(this.data, this.sharedMemPtr, false); } void CleanUp() { //Elimina i registri di sistema usati RegistryKey swKey = Registry.LocalMachine.CreateSubKey("Software"); swKey.DeleteSubKeyTree("SharedMemTest"); swKey.Close(); //Dealloca la memoria condivisa non gestita VirtualFree(this.sharedMemPtr, 0, DeallocationType.MEM_RELEASE); unsafe { IntPtr refrPtr = new IntPtr(this.mustRefresh); VirtualFree(refreshPtr, 0, DeallocationType.MEM_RELEASE); } VirtualFree(refreshPtr, 0, DeallocationType.MEM_RELEASE); }
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5