如何让 IntPtr 访问 MemoryMappedFile 的视图?
How to get an IntPtr to access the view of a MemoryMappedFile?
有没有办法直接 IntPtr
到 MemoryMappedFile 中的数据?
我的数据块很大,变化频率很高,我不想复制它
不,不是 IntPtr,这对你没有任何帮助。你可以得到一个byte*
,你可以随意转换它来访问实际的数据类型。如果需要,您可以将其转换为 IntPtr。必须使用 unsafe
关键字是有意为之的。
创建 MemoryMappedViewAccessor 以在 MMF 上创建视图。然后使用其SafeMemoryMappedViewHandle属性的AcquirePointer()方法获取byte*.
演示用法并显示各种指针恶作剧的示例程序:
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();
}
}
}
有没有办法直接 IntPtr
到 MemoryMappedFile 中的数据?
我的数据块很大,变化频率很高,我不想复制它
不,不是 IntPtr,这对你没有任何帮助。你可以得到一个byte*
,你可以随意转换它来访问实际的数据类型。如果需要,您可以将其转换为 IntPtr。必须使用 unsafe
关键字是有意为之的。
创建 MemoryMappedViewAccessor 以在 MMF 上创建视图。然后使用其SafeMemoryMappedViewHandle属性的AcquirePointer()方法获取byte*.
演示用法并显示各种指针恶作剧的示例程序:
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();
}
}
}