123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- using System;
- using System.ComponentModel;
- using System.Runtime.InteropServices;
- using System.Windows.Forms;
- namespace SmartCoalApplication.SystemLayer
- {
- public unsafe static class Memory
- {
- private static IntPtr hHeap;
- static Memory()
- {
- hHeap = SafeNativeMethods.HeapCreate(0, IntPtr.Zero, IntPtr.Zero);
- uint info = 2;
- try
- {
- SafeNativeMethods.HeapSetInformation(hHeap,
- NativeConstants.HeapCompatibilityInformation,
- (void*)&info,
- sizeof(uint));
- }
- catch (Exception)
- {
-
- }
- Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
- }
- private static void DestroyHeap()
- {
- IntPtr hHeap2 = hHeap;
- hHeap = IntPtr.Zero;
- SafeNativeMethods.HeapDestroy(hHeap2);
- }
- private static void Application_ApplicationExit(object sender, EventArgs e)
- {
- DestroyHeap();
- }
- public static IntPtr Allocate(ulong bytes)
- {
- if (hHeap == IntPtr.Zero)
- {
- throw new InvalidOperationException("heap has already been destroyed");
- }
- else
- {
- IntPtr block = SafeNativeMethods.HeapAlloc(hHeap, 0, new UIntPtr(bytes));
- if (block == IntPtr.Zero)
- {
- throw new OutOfMemoryException("HeapAlloc returned a null pointer");
- }
- if (bytes > 0)
- {
- GC.AddMemoryPressure((long)bytes);
- }
- return block;
- }
- }
-
- public static IntPtr AllocateLarge(ulong bytes)
- {
- IntPtr block = SafeNativeMethods.VirtualAlloc(IntPtr.Zero, new UIntPtr(bytes),
- NativeConstants.MEM_COMMIT, NativeConstants.PAGE_READWRITE);
- if (block == IntPtr.Zero)
- {
- throw new OutOfMemoryException("VirtualAlloc returned a null pointer");
- }
- if (bytes > 0)
- {
- GC.AddMemoryPressure((long)bytes);
- }
- return block;
- }
-
- public static IntPtr AllocateBitmap(int width, int height, out IntPtr handle)
- {
- NativeStructs.BITMAPINFO bmi = new NativeStructs.BITMAPINFO();
- bmi.bmiHeader.biSize = (uint)sizeof(NativeStructs.BITMAPINFOHEADER);
- bmi.bmiHeader.biWidth = width;
- bmi.bmiHeader.biHeight = -height;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 32;
- bmi.bmiHeader.biCompression = NativeConstants.BI_RGB;
- bmi.bmiHeader.biSizeImage = 0;
- bmi.bmiHeader.biXPelsPerMeter = 96;
- bmi.bmiHeader.biYPelsPerMeter = 96;
- bmi.bmiHeader.biClrUsed = 0;
- bmi.bmiHeader.biClrImportant = 0;
- IntPtr pvBits;
- IntPtr hBitmap = SafeNativeMethods.CreateDIBSection(
- IntPtr.Zero,
- ref bmi,
- NativeConstants.DIB_RGB_COLORS,
- out pvBits,
- IntPtr.Zero,
- 0);
- if (hBitmap == IntPtr.Zero)
- {
- throw new OutOfMemoryException("CreateDIBSection returned NULL (" + Marshal.GetLastWin32Error().ToString() + ") while attempting to allocate " + width + "x" + height + " bitmap");
- }
- handle = hBitmap;
- long bytes = (long)width * (long)height * 4;
- if (bytes > 0)
- {
- GC.AddMemoryPressure(bytes);
- }
- return pvBits;
- }
- /// <summary>
- /// Frees a bitmap previously allocated with AllocateBitmap.
- /// </summary>
- /// <param name="handle">The handle that was returned from a previous call to AllocateBitmap.</param>
- /// <param name="width">The width of the bitmap, as specified in the original call to AllocateBitmap.</param>
- /// <param name="height">The height of the bitmap, as specified in the original call to AllocateBitmap.</param>
- public static void FreeBitmap(IntPtr handle, int width, int height)
- {
- long bytes = (long)width * (long)height * 4;
- bool bResult = SafeNativeMethods.DeleteObject(handle);
- if (!bResult)
- {
- throw new Win32Exception("DeleteObject returned false");
- }
- if (bytes > 0)
- {
- GC.RemoveMemoryPressure(bytes);
- }
- }
- /// <summary>
- /// Frees a block of memory previously allocated with Allocate().
- /// </summary>
- /// <param name="block">The block to free.</param>
- /// <exception cref="InvalidOperationException">There was an error freeing the block.</exception>
- public static void Free(IntPtr block)
- {
- if (Memory.hHeap != IntPtr.Zero)
- {
- long bytes = (long)SafeNativeMethods.HeapSize(hHeap, 0, block);
- bool result = SafeNativeMethods.HeapFree(hHeap, 0, block);
- if (!result)
- {
- int error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
- throw new InvalidOperationException("HeapFree returned an error: " + error.ToString());
- }
- if (bytes > 0)
- {
- GC.RemoveMemoryPressure(bytes);
- }
- }
- }
- /// <summary>
- /// Frees a block of memory previous allocated with AllocateLarge().
- /// </summary>
- /// <param name="block">The block to free.</param>
- /// <param name="bytes">The size of the block.</param>
- public static void FreeLarge(IntPtr block, ulong bytes)
- {
- bool result = SafeNativeMethods.VirtualFree(block, UIntPtr.Zero, NativeConstants.MEM_RELEASE);
- if (!result)
- {
- int error = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
- throw new InvalidOperationException("VirtualFree returned an error: " + error.ToString());
- }
- if (bytes > 0)
- {
- GC.RemoveMemoryPressure((long)bytes);
- }
- }
- public static void Copy(void* dst, void* src, ulong length)
- {
- SafeNativeMethods.memcpy(dst, src, new UIntPtr(length));
- }
- public static void SetToZero(void* dst, ulong length)
- {
- SafeNativeMethods.memset(dst, 0, new UIntPtr(length));
- }
- }
- }
|