1. 程式人生 > >WinCE平臺下C#引用API(GDI)一個值得警惕的記憶體洩漏

WinCE平臺下C#引用API(GDI)一個值得警惕的記憶體洩漏

               

由於C#精簡框架集繪圖函式不支援圓角矩形,所以引用了相關的API。

 [DllImport("//windows//coredll.dll", EntryPoint = "RoundRect")]        private static extern int CeRoundRect(IntPtr hdc, int X1, int Y1, int X2, int Y2, int X3, int Y3);

 這是有記憶體洩漏的原始碼:

 public static int RoundRect(Graphics e, Pen pen, SolidBrush brush, int X1, int Y1, int X2, int Y2, int X3, int Y3)        {                     IntPtr hpen;            IntPtr hbrush;

            if(pen!=null)            {                hpen = CreatePen((DashStyle.Solid == pen.DashStyle) ? 0 : 1,                (int)pen.Width, SetRGB(pen.Color.R, pen.Color.G, pen.Color.B));      //建立GDI畫筆              }            else            {                hpen = GetStockObject(8);      //空畫筆            }         

            if (brush!= null)            {                hbrush = CreateSolidBrush(SetRGB(brush.Color.R, brush.Color.G, brush.Color.B)); //brush.Color.ToArgb());            }            else            {                hbrush = GetStockObject(5);            }

            //pen.Dispose();            //brush.Dispose();

            IntPtr hdc = e.GetHdc();            //---------------------                SelectObject(hdc, hbrush);             SelectObject(hdc, hpen);            int intRet=RoundRect(hdc, X1, Y1, X2,Y2, X3, Y3);

            DeleteObject(hbrush);            DeleteObject(hpen);            //---------------------            e.ReleaseHdc(hdc);            return intRet;        }

這是沒有問題的原始碼:

 public static int RoundRect(Graphics e, Pen pen, SolidBrush brush, int X1, int Y1, int X2, int Y2, int X3, int Y3)        {                     IntPtr hpen,old_pen;            IntPtr hbrush, old_brush;

            if(pen!=null)            {                hpen = CreatePen((DashStyle.Solid == pen.DashStyle) ? 0 : 1,                (int)pen.Width, SetRGB(pen.Color.R, pen.Color.G, pen.Color.B));      //建立GDI畫筆              }            else            {                hpen = GetStockObject(8);      //空畫筆            }         

            if (brush!= null)            {                hbrush = CreateSolidBrush(SetRGB(brush.Color.R, brush.Color.G, brush.Color.B)); //brush.Color.ToArgb());            }            else            {                hbrush = GetStockObject(5);            }

            //pen.Dispose();            //brush.Dispose();

            IntPtr hdc = e.GetHdc();            //---------------------               old_brush=SelectObject(hdc, hbrush);            old_pen=SelectObject(hdc, hpen);                        int intRet=RoundRect(hdc, X1, Y1, X2,Y2, X3, Y3);

            SelectObject(hdc, old_brush);            SelectObject(hdc, old_pen);            DeleteObject(hbrush);            DeleteObject(hpen);            //---------------------            e.ReleaseHdc(hdc);            return intRet;        }

       看出程式碼的區別來了沒有?洩漏的原因其實很簡單,就是沒有重新選入舊的畫筆畫刷。同樣的程式(當然PC端的API庫是GDI32)在上位機Window XP平臺上沒有什麼問題(測試大約3天以上),而在WinCE平臺確非常明顯,大約1~3個小時(視圓角矩形繪圖的多寡而定),該程式就會記憶體耗盡而死。