IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    略谈GCHandle【转】

    天下发表于 2015-12-21 10:36:00
    love 0


    略谈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。


    天下 2015-12-21 18:36 发表评论


沪ICP备19023445号-2号
友情链接