Is there a way to get a direct IntPtr
to the data in a MemoryMappedFile?
I have large data block with high frequency change and I don't want to copy it
No, not an IntPtr, that doesn't help you anyway. You can get a byte*
, you can cast it at will to access the actual data type. And you can cast it to IntPtr if you have to. Having to use the unsafe
keyword is quite intentional.
Create a MemoryMappedViewAccessor to create the view on the MMF. Then use the AcquirePointer() method of its SafeMemoryMappedViewHandle property to obtain the byte*.
A sample program that demonstrates the usage and shows various pointer shenanigans:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
class Program {
static unsafe void Main(string[] args) {
using (var mmf = System.IO.MemoryMappedFiles.MemoryMappedFile.CreateNew("test", 42))
using (var view = mmf.CreateViewAccessor()) {
byte* poke = null;
view.SafeMemoryMappedViewHandle.AcquirePointer(ref poke);
*(int*)poke = 0x12345678;
Debug.Assert(*poke == 0x78);
Debug.Assert(*(poke + 1) == 0x56);
Debug.Assert(*(short*)poke == 0x5678);
Debug.Assert(*((short*)poke + 1) == 0x1234);
Debug.Assert(*(short*)(poke + 2) == 0x1234);
IntPtr ipoke = (IntPtr)poke;
Debug.Assert(Marshal.ReadInt32(ipoke) == 0x12345678);
*(poke + 1) = 0xab;
Debug.Assert(Marshal.ReadInt32(ipoke) == 0x1234ab78);
view.SafeMemoryMappedViewHandle.ReleasePointer();
}
}
}