天下

记录修行的印记

略谈GCHandle【转】



略谈GCHandle【转】
http://blog.163.com/vk_01313/blog/static/17219228200912491729457/
我们在使用c#托管代码时,内存地址和GC回收那不是我们关心的,CLR已经给我们暗箱操作。
但是如果我们在c#中调用了一个非托管代码,比如vc的DLL,而且他有个回调函数,需要引用c#中的某个对象并操作,
这时候你就得要小心了。
要是非托管代码中用到得托管代码那个对象被GC给回收了,这时候就会报内存错误。
所以我们就要把那个对象“钉”住(pin),让它的内存地址固定,而不被垃圾回收掉,然后最后我们自己管理,自己释放内存,这时候就需要GCHandle,来看个msdn上的例子:


using System.Runtime.InteropServices;

namespace ConsoleApplication1
{

    //C#
    public delegate bool CallBack(int handle, IntPtr param);
    public class LibWrap
    {
        [DllImport("user32.dll")]
        public static extern bool EnumWindows(CallBack cb, IntPtr param);
    }

    class Program
    {
        static void Main(string[] args)
        {
            TextWriter tw = System.Console.Out;
            GCHandle gch = GCHandle.Alloc(tw);
            CallBack cewp = new CallBack(CaptureEnumWindowsProc);
            LibWrap.EnumWindows(cewp, (IntPtr)gch);
            gch.Free();
            Console.Read();

        }
        private static bool CaptureEnumWindowsProc(int handle, IntPtr param)
        {
            GCHandle gch = (GCHandle)param;
            TextWriter tw = (TextWriter)gch.Target;
            tw.WriteLine(handle);
            return true;
        }

    } 
}


对上面的代码,略加解释:gch 会钉住(pin)tw这个对象,使其不受GC管理,告诉它,以后你崩管我,我也不用给你上税,其实管理权已经给gch,通过free来释放内存。
这种情况主要用在托管和非托管代码交互的时候,防止内存泄露来使用GCHandle。

posted on 2015-12-21 18:36 天下 阅读(936) 评论(0)  编辑 收藏 引用 所属分类: C#


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2013年3月>
242526272812
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

常用链接

留言簿(4)

随笔分类(378)

随笔档案(329)

链接

最新随笔

搜索

最新评论