MS公开的gchandle.cs源码

 

  1 None.gif //  ==++==
  2 None.gif //  
  3 None.gif //    
  4 None.gif //     Copyright (c) 2002 Microsoft Corporation.  All rights reserved.
  5 None.gif //    
  6 None.gif //     The use and distribution terms for this software are contained in the file
  7 None.gif //     named license.txt, which can be found in the root of this distribution.
  8 None.gif //     By using this software in any fashion, you are agreeing to be bound by the
  9 None.gif //     terms of this license.
 10 None.gif //    
 11 None.gif //     You must not remove this notice, or any other, from this software.
 12 None.gif //    
 13 None.gif //  
 14 None.gif //  ==--==
 15 ExpandedBlockStart.gifContractedBlock.gif namespace  System.Runtime.InteropServices  dot.gif {
 16InBlock.gif    
 17InBlock.gif using System;
 18InBlock.gif using System.Security.Permissions;
 19InBlock.gif using System.Runtime.CompilerServices;
 20InBlock.gif
 21InBlock.gif // These are the types of handles used by the EE.  IMPORTANT: These must
 22InBlock.gif // match the definitions in ObjectHandle.h in the EE.
 23ExpandedSubBlockStart.gifContractedSubBlock.gif /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandleType"]/*' />
 24InBlock.gif [Serializable]
 25InBlock.gif public enum GCHandleType
 26ExpandedSubBlockStart.gifContractedSubBlock.gif dot.gif{
 27ExpandedSubBlockStart.gifContractedSubBlock.gif  /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandleType.Weak"]/*' />
 28InBlock.gif  Weak = 0,
 29ExpandedSubBlockStart.gifContractedSubBlock.gif  /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandleType.WeakTrackResurrection"]/*' />
 30InBlock.gif  WeakTrackResurrection = 1,
 31ExpandedSubBlockStart.gifContractedSubBlock.gif  /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandleType.Normal"]/*' />
 32InBlock.gif  Normal = 2,
 33ExpandedSubBlockStart.gifContractedSubBlock.gif  /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandleType.Pinned"]/*' />
 34InBlock.gif  Pinned = 3
 35ExpandedSubBlockEnd.gif }

 36InBlock.gif
 37InBlock.gif    // This class allows you to create an opaque, GC handle to any 
 38InBlock.gif    // COM+ object. A GC handle is used when an object reference must be
 39InBlock.gif // reachable from unmanaged memory.  There are 3 kinds of roots:
 40InBlock.gif // Normal - keeps the object from being collected.
 41InBlock.gif // Weak - allows object to be collected and handle contents will be zeroed.
 42InBlock.gif    //          Weak references are zeroed before the finalizer runs, so if the
 43InBlock.gif    //          object is resurrected in the finalizer the weak reference is
 44InBlock.gif    //          still zeroed.
 45InBlock.gif // WeakTrackResurrection - Same as weak, but stays until after object is
 46InBlock.gif    //          really gone.
 47InBlock.gif // Pinned - same as normal, but allows the address of the actual object
 48InBlock.gif //          to be taken.
 49InBlock.gif    //
 50ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle"]/*' />
 51InBlock.gif [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
 52InBlock.gif    public struct GCHandle
 53ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 54InBlock.gif        // Allocate a handle storing the object and the type.
 55InBlock.gif        internal GCHandle(Object value, GCHandleType type)
 56ExpandedSubBlockStart.gifContractedSubBlock.gif  dot.gif{
 57InBlock.gif   m_handle = InternalAlloc(value, type);
 58InBlock.gif
 59InBlock.gif   // Record if the handle is pinned.
 60InBlock.gif   if (type == GCHandleType.Pinned)
 61InBlock.gif                SetIsPinned();
 62ExpandedSubBlockEnd.gif  }
  
 63InBlock.gif
 64InBlock.gif  // Used in the conversion functions below.
 65InBlock.gif  internal GCHandle(IntPtr handle)
 66ExpandedSubBlockStart.gifContractedSubBlock.gif  dot.gif{
 67InBlock.gif         InternalCheckDomain(handle);
 68InBlock.gif   m_handle = handle;
 69ExpandedSubBlockEnd.gif  }

 70InBlock.gif
 71InBlock.gif        // Creates a new GC handle for an object.
 72InBlock.gif        //
 73InBlock.gif        // value - The object that the GC handle is created for.
 74InBlock.gif  // type - The type of GC handle to create.
 75InBlock.gif        // 
 76InBlock.gif     // returns a new GC handle that protects the object.
 77ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.Alloc"]/*' />
 78InBlock.gif        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
 79InBlock.gif        public static GCHandle Alloc(Object value)
 80ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 81InBlock.gif   return new GCHandle(value, GCHandleType.Normal);
 82ExpandedSubBlockEnd.gif        }

 83InBlock.gif
 84ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.Alloc1"]/*' />
 85InBlock.gif        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
 86InBlock.gif        public static GCHandle Alloc(Object value, GCHandleType type)
 87ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 88InBlock.gif   return new GCHandle(value, type);
 89ExpandedSubBlockEnd.gif        }

 90InBlock.gif
 91InBlock.gif        // Frees a GC handle.  The caller must provide synchronization to
 92InBlock.gif  // prevent multiple threads from executing this simultaneously for
 93InBlock.gif  // a given handle. If you modify this method please modify the 
 94InBlock.gif        // __InternalFree also which is the internal without the linktime check.
 95ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.Free"]/*' />
 96InBlock.gif        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
 97InBlock.gif        public void Free()
 98ExpandedSubBlockStart.gifContractedSubBlock.gif  dot.gif{
 99InBlock.gif   // Check if the handle was never initialized for was freed.
100InBlock.gif   if (m_handle == IntPtr.Zero)
101InBlock.gif    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
102InBlock.gif
103InBlock.gif   // Free the handle.
104InBlock.gif   InternalFree(GetHandleValue());
105InBlock.gif   m_handle = IntPtr.Zero;
106ExpandedSubBlockEnd.gif  }

107InBlock.gif  
108InBlock.gif  internal void __InternalFree()
109ExpandedSubBlockStart.gifContractedSubBlock.gif  dot.gif{
110InBlock.gif   // Check if the handle was never initialized for was freed.
111InBlock.gif   if (m_handle == IntPtr.Zero)
112InBlock.gif    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
113InBlock.gif
114InBlock.gif   // Free the handle.
115InBlock.gif   InternalFree(GetHandleValue());
116InBlock.gif   m_handle = IntPtr.Zero;
117ExpandedSubBlockEnd.gif  }

118InBlock.gif
119InBlock.gif        // Target property - allows getting / updating of the handle's referent. If you modify this method
120InBlock.gif
121InBlock.gif        // then modify the __InternalTarget too which is the internal method without the linktime check.
122ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.Target"]/*' />
123InBlock.gif        public Object Target
124ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
125InBlock.gif         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
126InBlock.gif            get
127ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
128InBlock.gif                // Check if the handle was never initialized or was freed.
129InBlock.gif    if (m_handle == IntPtr.Zero)
130InBlock.gif     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
131InBlock.gif
132InBlock.gif                return InternalGet(GetHandleValue());
133ExpandedSubBlockEnd.gif            }

134InBlock.gif    
135InBlock.gif         [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
136InBlock.gif            set
137ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
138InBlock.gif                // Check if the handle was never initialized or was freed.
139InBlock.gif    if (m_handle == IntPtr.Zero)
140InBlock.gif     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
141InBlock.gif
142InBlock.gif                InternalSet(GetHandleValue(), value, IsPinned());
143ExpandedSubBlockEnd.gif            }

144ExpandedSubBlockEnd.gif        }

145InBlock.gif        
146InBlock.gif        internal Object __InternalTarget
147ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
148InBlock.gif            get
149ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
150InBlock.gif                // Check if the handle was never initialized or was freed.
151InBlock.gif    if (m_handle == IntPtr.Zero)
152InBlock.gif     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
153InBlock.gif
154InBlock.gif                return InternalGet(GetHandleValue());
155ExpandedSubBlockEnd.gif            }

156ExpandedSubBlockEnd.gif        }

157InBlock.gif
158InBlock.gif        // Retrieve the address of an object in a Pinned handle.  This throws
159InBlock.gif  // an exception if the handle is any type other than Pinned.
160ExpandedSubBlockStart.gifContractedSubBlock.gif  /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.AddrOfPinnedObject"]/*' />
161InBlock.gif        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
162InBlock.gif  public IntPtr AddrOfPinnedObject()
163ExpandedSubBlockStart.gifContractedSubBlock.gif  dot.gif{
164InBlock.gif   // Check if the handle was not a pinned handle.
165InBlock.gif   if (!IsPinned())
166ExpandedSubBlockStart.gifContractedSubBlock.gif   dot.gif{
167InBlock.gif    // Check if the handle was never initialized for was freed.
168InBlock.gif    if (m_handle == IntPtr.Zero)
169InBlock.gif     throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotInitialized"));
170InBlock.gif
171InBlock.gif    // You can only get the address of pinned handles.
172InBlock.gif    throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotPinned"));
173ExpandedSubBlockEnd.gif   }

174InBlock.gif
175InBlock.gif   // Get the address.
176InBlock.gif   return InternalAddrOfPinnedObject(GetHandleValue());
177ExpandedSubBlockEnd.gif  }

178InBlock.gif
179InBlock.gif        // Determine whether this handle has been allocated or not.
180ExpandedSubBlockStart.gifContractedSubBlock.gif  /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.IsAllocated"]/*' />
181InBlock.gif  public bool IsAllocated
182ExpandedSubBlockStart.gifContractedSubBlock.gif  dot.gif{
183InBlock.gif   get
184ExpandedSubBlockStart.gifContractedSubBlock.gif   dot.gif{
185InBlock.gif    return m_handle != IntPtr.Zero;
186ExpandedSubBlockEnd.gif   }

187ExpandedSubBlockEnd.gif  }

188InBlock.gif
189InBlock.gif        // Used to create a GCHandle from an int.  This is intended to
190InBlock.gif  // be used with the reverse conversion.
191ExpandedSubBlockStart.gifContractedSubBlock.gif     /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.operatorGCHandle"]/*' />
192InBlock.gif        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
193InBlock.gif     public static explicit operator GCHandle(IntPtr value)
194ExpandedSubBlockStart.gifContractedSubBlock.gif  dot.gif{
195InBlock.gif            return new GCHandle(value);
196ExpandedSubBlockEnd.gif        }

197InBlock.gif
198InBlock.gif // Used to get the internal integer representation of the handle out.
199ExpandedSubBlockStart.gifContractedSubBlock.gif     /**//// <include file='doc\GcHandle.uex' path='docs/doc[@for="GCHandle.operatorIntPtr"]/*' />
200InBlock.gif     public static explicit operator IntPtr(GCHandle value)
201ExpandedSubBlockStart.gifContractedSubBlock.gif  dot.gif{
202InBlock.gif            return value.m_handle;
203ExpandedSubBlockEnd.gif        }

204InBlock.gif
205InBlock.gif        internal IntPtr GetHandleValue()
206ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
207InBlock.gif#if WIN32
208InBlock.gif            return new IntPtr(((int)m_handle) & ~1);
209InBlock.gif#else
210InBlock.gif            return new IntPtr(((long)m_handle) & ~1L);
211InBlock.gif#endif
212ExpandedSubBlockEnd.gif        }

213InBlock.gif
214InBlock.gif        internal bool IsPinned()
215ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
216InBlock.gif#if WIN32
217InBlock.gif            return (((int)m_handle) & 1!= 0;
218InBlock.gif#else
219InBlock.gif            return (((long)m_handle) & 1!= 0;
220InBlock.gif#endif
221ExpandedSubBlockEnd.gif        }

222InBlock.gif
223InBlock.gif        internal void SetIsPinned()
224ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
225InBlock.gif#if WIN32
226InBlock.gif            m_handle = new IntPtr(((int)m_handle) | 1);
227InBlock.gif#else
228InBlock.gif            m_handle = new IntPtr(((long)m_handle) | 1L);
229InBlock.gif#endif
230ExpandedSubBlockEnd.gif        }

231InBlock.gif
232InBlock.gif  // Internal native calls that this implementation uses.
233InBlock.gif        [MethodImplAttribute(MethodImplOptions.InternalCall)]
234InBlock.gif  internal static extern IntPtr InternalAlloc(Object value, GCHandleType type);
235InBlock.gif        [MethodImplAttribute(MethodImplOptions.InternalCall)]
236InBlock.gif        internal static extern void InternalFree(IntPtr handle);
237InBlock.gif        [MethodImplAttribute(MethodImplOptions.InternalCall)]
238InBlock.gif        internal static extern Object InternalGet(IntPtr handle);
239InBlock.gif        [MethodImplAttribute(MethodImplOptions.InternalCall)]
240InBlock.gif        internal static extern void InternalSet(IntPtr handle, Object value, bool isPinned);
241InBlock.gif        [MethodImplAttribute(MethodImplOptions.InternalCall)]
242InBlock.gif        internal static extern void InternalCompareExchange(IntPtr handle, Object value, Object oldValue, bool isPinned);
243InBlock.gif        [MethodImplAttribute(MethodImplOptions.InternalCall)]
244InBlock.gif  internal static extern IntPtr InternalAddrOfPinnedObject(IntPtr handle);
245InBlock.gif        [MethodImplAttribute(MethodImplOptions.InternalCall)]
246InBlock.gif  internal static extern void InternalCheckDomain(IntPtr handle);
247InBlock.gif
248InBlock.gif
249InBlock.gif  // The actual integer handle value that the EE uses internally.
250InBlock.gif  private IntPtr m_handle;
251ExpandedSubBlockEnd.gif    }

252ExpandedBlockEnd.gif}

253 None.gif
254 None.gif

转载于:https://www.cnblogs.com/wannaCNBLOGS/archive/2005/08/04/207070.html

### 回答1: gchandle.alloc 和 gchandletype.pinned 是.NET框架中用于管理非托管资源的类和枚举。 gchandle.alloc 是一个方法,它用于在托管代码中分配一个句柄来引用非托管资源。在进行本地互操作(P/Invoke)时,我们可能需要引用一些非托管资源,如指针、结构体等。使用 gchandle.alloc 方法可以分配一个句柄来引用这些非托管资源,以便在托管代码中对其进行操作。 gchandletype.pinned 是一个枚举类型,它用于指定句柄的类型。其中,pinned 表示句柄是固定的,也就是说,垃圾回收器不会移动该资源的内存位置。这在需要长时间持有非托管资源的情况下很有用,因为如果资源的地址发生变化,那么之前的引用将失效。 当我们在托管代码中使用 gchandle.alloc 方法分配一个句柄时,我们可以通过指定 gchandletype.pinned 来固定句柄所引用的非托管资源的内存位置,以确保在使用过程中不会被回收或重新分配。 需要注意的是,使用非托管资源时应谨慎操作,确保资源的正确释放和管理。如果没有适当地释放非托管资源,可能会导致内存泄漏或其他问题。因此,在使用 gchandle.alloc 和 gchandletype.pinned 时,应遵循正确的资源管理和释放的最佳实践。 ### 回答2: gchandle.alloc和gchandle类型pinned是在C#中用于管理非托管内存的相关概念。 gchandle.alloc是一个方法,它在托管堆之外为非托管资源分配内存块,并返回一个指向该内存块的句柄(GCHandle)。这个句柄可以用来将托管对象与非托管内存块关联起来。 gchandle类型pinned是作为gchandle句柄的一种类型。当一个对象与非托管内存块关联时,gchandle类型pinned确保该对象在垃圾回收过程中不会被移动或释放。这样可以防止由于垃圾回收过程中对象的移动而导致的非托管内存块地址无效的问题。 通过使用gchandle.alloc和gchandle类型pinned,我们可以有效地管理非托管资源。首先,我们使用gchandle.alloc为非托管资源分配内存块,并获取一个gchandle句柄。然后,我们可以使用该句柄将托管对象与非托管内存块关联起来。同时,我们可以使用gchandle类型pinned确保相关对象在垃圾回收过程中的安全性,避免非托管内存地址无效的问题。 总之,gchandle.alloc和gchandle类型pinned是C#中用于管理非托管内存的重要概念。它们提供了一种有效的方式来管理非托管资源,并确保与之关联的对象在垃圾回收过程中的安全性。 ### 回答3: gchandle.alloc和gchandle类型.pinned是.NET框架中用于管理托管和非托管对象之间的GC句柄的方法和类型。 gchandle.alloc是一个用于分配GC句柄的方法。在.NET框架中,当处理非托管资源时,需要使用GC句柄来确保垃圾收集器不会对该资源进行回收。通过调用gchandle.alloc方法,可以分配一个新的GC句柄,并将其用于托管对象和非托管资源之间的交互。这个方法通常在需要操作非托管资源的时候使用,比如使用本机代码或与第三方库进行交互时。 gchandle类型.pinned是一种GC句柄类型,表示被锁定的对象。当一个对象被锁定时,垃圾收集器无法将其回收,直到该对象被解锁。通过将对象的句柄设置为gchandle类型.pinned,可以确保对象在特定代码块中保持稳定,从而避免在使用非托管资源时发生内存泄漏或对象被回收。 综上所述,gchandle.alloc和gchandle类型.pinned都是.NET框架中用于处理托管和非托管资源之间交互的重要概念。通过使用gchandle.alloc方法分配GC句柄,并将句柄设置为gchandle类型.pinned,可以确保托管对象与非托管资源之间的稳定交互,从而提高应用程序的性能和安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值