MS公开的gchandle.cs源码

该博客为转载内容,原文链接为https://www.cnblogs.com/wannaCNBLOGS/archive/2005/08/04/207070.html ,涉及runtime相关内容。

 

  1None.gif// ==++==
  2None.gif// 
  3None.gif//   
  4None.gif//    Copyright (c) 2002 Microsoft Corporation.  All rights reserved.
  5None.gif//   
  6None.gif//    The use and distribution terms for this software are contained in the file
  7None.gif//    named license.txt, which can be found in the root of this distribution.
  8None.gif//    By using this software in any fashion, you are agreeing to be bound by the
  9None.gif//    terms of this license.
 10None.gif//   
 11None.gif//    You must not remove this notice, or any other, from this software.
 12None.gif//   
 13None.gif// 
 14None.gif// ==--==
 15ExpandedBlockStart.gifContractedBlock.gifnamespace 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}

253None.gif
254None.gif

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值