我想知道Marshal.GetFunctionPointerForDelegate。也就是说,我想知道如何将委托(delegate)转换为非静态的函数并转换为函数指针。
它是否动态生成以某种方式附加了实例的代码 stub ?如果是这样,这不是泄漏内存吗?也许代表在其终结器中释放了它?
它看起来不像System.Delegate具有终结器,所以我对这种机制的工作方式非常感兴趣。我假设函数指针需要4个字节,实例需要4个字节(在32位上),但是它返回一个简单的IntPtr。
最佳答案
很大的问题是,与会代表在CLR中与他们相关联的代码冰山一角。所以只是一些提示。下载SSCLI20 distribution以查看源代码。所有相关代码在clr/src/vm子目录中。
UMEntryThunk是编码(marshal)调用的thunk的包装。它由comdelegate.cpp中的COMDelegate::ConvertToCallback()创建,由MarshalNative::GetFunctionPointerForDelegateInternal()(即Marshal方法的内部实现)调用。
指向UMEntryThunk的指针存储在委托(delegate)对象syncblk.h,InteropSyncBlockInfo::SetUMEntryThunk()方法的syncblk中。
当垃圾回收器销毁委托(delegate)对象时,它也会为其清理syncblk,并调用〜InteropSyncBlockInfo析构函数。它将调用UMEntryThunk::FreeUMEntryThunk()方法,该方法将再次清理垃圾。
因此,不,没有内存泄漏。不完全是终结器,只是常规GC清理的一部分。