WinCE平台下C#引用API(GDI)一个值得警惕的内存泄漏

    技术2022-05-11  52

    由于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个小时(视圆角矩形绘图的多寡而定),该程序就会内存耗尽而死。

     

    最新回复(0)