2 // System.Runtime.InteropServices.GCHandle Test Cases
5 // Paolo Molaro (lupus@ximian.com)
7 // Copyright (C) 2005, 2009 Novell, Inc (http://www.novell.com)
10 using NUnit.Framework;
12 using System.Reflection;
13 using System.Runtime.InteropServices;
14 using System.Globalization;
16 namespace MonoTests.System.Runtime.InteropServices
19 public class GCHandleTest
21 static GCHandle handle;
24 public void DefaultZeroValue_Allocated ()
26 Assert.IsFalse (handle.IsAllocated, "IsAllocated");
30 [ExpectedException (typeof (InvalidOperationException))]
31 public void DefaultZeroValue_Target ()
33 Assert.IsNull (handle.Target, "Target");
37 public void AllocNull ()
39 IntPtr ptr = (IntPtr) GCHandle.Alloc (null);
40 Assert.IsFalse (ptr == IntPtr.Zero, "ptr");
41 GCHandle gch = (GCHandle) ptr;
42 Assert.IsTrue (gch.IsAllocated, "IsAllocated");
43 Assert.IsNull (gch.Target, "Target");
47 public void AllocNullWeakTrack ()
49 GCHandle gch = GCHandle.Alloc (null, GCHandleType.WeakTrackResurrection);
50 Assert.IsTrue (gch.IsAllocated, "IsAllocated");
51 Assert.IsNull (gch.Target, "Target");
55 [ExpectedException (typeof (InvalidOperationException))]
56 public void AddrOfPinnedObjectNormal ()
58 GCHandle handle = GCHandle.Alloc (new Object (), GCHandleType.Normal);
60 IntPtr ptr = handle.AddrOfPinnedObject();
68 [ExpectedException (typeof (InvalidOperationException))]
69 public void AddrOfPinnedObjectWeak ()
71 GCHandle handle = GCHandle.Alloc (new Object (), GCHandleType.Weak);
73 IntPtr ptr = handle.AddrOfPinnedObject();
81 [ExpectedException (typeof (InvalidOperationException))]
82 public void AddrOfPinnedObjectWeakTrackResurrection ()
84 GCHandle handle = GCHandle.Alloc (new Object (), GCHandleType.WeakTrackResurrection);
86 IntPtr ptr = handle.AddrOfPinnedObject();
94 public void AddrOfPinnedObjectNull ()
96 GCHandle handle = GCHandle.Alloc (null, GCHandleType.Pinned);
98 IntPtr ptr = handle.AddrOfPinnedObject();
99 Assert.AreEqual (new IntPtr (0), ptr);
107 [Ignore ("throw non-catchable ExecutionEngineException")]
108 [ExpectedException (typeof (ExecutionEngineException))]
109 public void AllocMinusOne ()
111 // -1 is a special value used by the mono runtime
112 // looks like it's special too in MS CLR (since it will crash)
113 GCHandle.Alloc (null, (GCHandleType) (-1));
117 public void AllocInvalidType ()
119 GCHandle gch = GCHandle.Alloc (null, (GCHandleType) Int32.MinValue);
121 Assert.IsTrue (gch.IsAllocated, "IsAllocated");
122 Assert.IsNull (gch.Target, "Target");
130 public void WeakHandleWorksOnNonRootDomain ()
132 //Console.WriteLine("current app domain: " + AppDomain.CurrentDomain.Id);
133 AppDomain domain = AppDomain.CreateDomain("testdomain");
135 Assembly ea = Assembly.GetExecutingAssembly ();
136 domain.CreateInstanceFrom (ea.CodeBase,
137 typeof (AssemblyResolveHandler).FullName,
139 BindingFlags.Public | BindingFlags.Instance,
141 new object [] { ea.Location, ea.FullName },
142 CultureInfo.InvariantCulture,
147 var testerType = typeof (CrossDomainGCHandleRunner);
148 var r = (CrossDomainGCHandleRunner)domain.CreateInstanceAndUnwrap (
149 testerType.Assembly.FullName, testerType.FullName, false,
150 BindingFlags.Public | BindingFlags.Instance, null, new object [0],
151 CultureInfo.InvariantCulture, new object [0], null);
154 Assert.IsTrue (r.RunTest (), "#1");
155 AppDomain.Unload (domain);
158 public class CrossDomainGCHandleRunner : MarshalByRefObject {
159 public bool RunTest () {
160 object o = new object();
161 GCHandle gcHandle = GCHandle.Alloc (o, GCHandleType.Weak);
162 IntPtr intPtr = (IntPtr)gcHandle;
165 object target = GCHandle.FromIntPtr(intPtr).Target;
167 } catch (Exception) {}
173 class AssemblyResolveHandler
175 public AssemblyResolveHandler (string assemblyFile, string assemblyName)
177 _assemblyFile = assemblyFile;
178 _assemblyName = assemblyName;
180 AppDomain.CurrentDomain.AssemblyResolve +=
181 new ResolveEventHandler (ResolveAssembly);
184 private Assembly ResolveAssembly (object sender, ResolveEventArgs args)
186 if (args.Name == _assemblyName)
187 return Assembly.LoadFrom (_assemblyFile);
192 private readonly string _assemblyFile;
193 private readonly string _assemblyName;