static void ValidateComInterfaceCreation() { Console.WriteLine($"Running {nameof(ValidateComInterfaceCreation)}..."); var testObj = new Test(); var wrappers = new TestComWrappers(); // Allocate a wrapper for the object IntPtr comWrapper = wrappers.GetOrCreateComInterfaceForObject(testObj, CreateComInterfaceFlags.TrackerSupport); Assert.AreNotEqual(comWrapper, IntPtr.Zero); // Get a wrapper for an object and verify it is the same one. IntPtr comWrapperMaybe = wrappers.GetOrCreateComInterfaceForObject(testObj, CreateComInterfaceFlags.TrackerSupport); Assert.AreEqual(comWrapper, comWrapperMaybe); // Release the wrapper int count = Marshal.Release(comWrapper); Assert.AreEqual(count, 1); count = Marshal.Release(comWrapperMaybe); Assert.AreEqual(count, 0); // Create a new wrapper IntPtr comWrapperNew = wrappers.GetOrCreateComInterfaceForObject(testObj, CreateComInterfaceFlags.TrackerSupport); // Once a wrapper is created for a managed object it is always present Assert.AreEqual(comWrapperNew, comWrapper); // Release the new wrapper count = Marshal.Release(comWrapperNew); Assert.AreEqual(count, 0); }
static void ValidateFallbackQueryInterface() { Console.WriteLine($"Running {nameof(ValidateFallbackQueryInterface)}..."); var testObj = new Test() { EnableICustomQueryInterface = true }; var wrappers = new TestComWrappers(); // Allocate a wrapper for the object IntPtr comWrapper = wrappers.GetOrCreateComInterfaceForObject(testObj, CreateComInterfaceFlags.None); testObj.ICustomQueryInterface_GetInterfaceResult = new IntPtr(0x2000000); IntPtr result; var anyGuid = new Guid("1E42439C-DCB5-4701-ACBD-87FE92E785DE"); testObj.ICustomQueryInterface_GetInterfaceIID = anyGuid; int hr = Marshal.QueryInterface(comWrapper, ref anyGuid, out result); Assert.AreEqual(hr, 0); Assert.AreEqual(result, testObj.ICustomQueryInterface_GetInterfaceResult); var anyGuid2 = new Guid("7996D0F9-C8DD-4544-B708-0F75C6FF076F"); hr = Marshal.QueryInterface(comWrapper, ref anyGuid2, out result); const int E_NOINTERFACE = unchecked ((int)0x80004002); Assert.AreEqual(hr, E_NOINTERFACE); Assert.AreEqual(result, IntPtr.Zero); }
static void ValidateWrappersInstanceIsolation() { Console.WriteLine($"Running {nameof(ValidateWrappersInstanceIsolation)}..."); var cw1 = new TestComWrappers(); var cw2 = new TestComWrappers(); var testObj = new Test(); // Allocate a wrapper for the object IntPtr comWrapper1 = cw1.GetOrCreateComInterfaceForObject(testObj, CreateComInterfaceFlags.TrackerSupport); IntPtr comWrapper2 = cw2.GetOrCreateComInterfaceForObject(testObj, CreateComInterfaceFlags.TrackerSupport); Assert.AreNotEqual(comWrapper1, IntPtr.Zero); Assert.AreNotEqual(comWrapper2, IntPtr.Zero); Assert.AreNotEqual(comWrapper1, comWrapper2); IntPtr comWrapper3 = cw1.GetOrCreateComInterfaceForObject(testObj, CreateComInterfaceFlags.TrackerSupport); IntPtr comWrapper4 = cw2.GetOrCreateComInterfaceForObject(testObj, CreateComInterfaceFlags.TrackerSupport); Assert.AreNotEqual(comWrapper3, comWrapper4); Assert.AreEqual(comWrapper1, comWrapper3); Assert.AreEqual(comWrapper2, comWrapper4); Marshal.Release(comWrapper1); Marshal.Release(comWrapper2); Marshal.Release(comWrapper3); Marshal.Release(comWrapper4); // Get an object from a tracker runtime. IntPtr trackerObjRaw = MockReferenceTrackerRuntime.CreateTrackerObject(); // Create objects for the COM instance var trackerObj1 = (ITrackerObjectWrapper)cw1.GetOrCreateObjectForComInstance(trackerObjRaw, CreateObjectFlags.TrackerObject); var trackerObj2 = (ITrackerObjectWrapper)cw2.GetOrCreateObjectForComInstance(trackerObjRaw, CreateObjectFlags.TrackerObject); Assert.AreNotEqual(trackerObj1, trackerObj2); var trackerObj3 = (ITrackerObjectWrapper)cw1.GetOrCreateObjectForComInstance(trackerObjRaw, CreateObjectFlags.TrackerObject); var trackerObj4 = (ITrackerObjectWrapper)cw2.GetOrCreateObjectForComInstance(trackerObjRaw, CreateObjectFlags.TrackerObject); Assert.AreNotEqual(trackerObj3, trackerObj4); Assert.AreEqual(trackerObj1, trackerObj3); Assert.AreEqual(trackerObj2, trackerObj4); Marshal.Release(trackerObjRaw); }
public DerivedObject(TestComWrappers comWrappersInstance) { IntPtr innerInstance = WeakReferenceNative.CreateAggregatedWeakReferenceObject( comWrappersInstance.GetOrCreateComInterfaceForObject(this, CreateComInterfaceFlags.None)); inner = new WeakReferenceableWrapper(innerInstance, comWrappersInstance.Registration, releaseInFinalizer: false); comWrappersInstance.GetOrRegisterObjectForComInstance(innerInstance, CreateObjectFlags.Aggregation, this); }
static void ValidateRuntimeTrackerScenario() { Console.WriteLine($"Running {nameof(ValidateRuntimeTrackerScenario)}..."); var cw = new TestComWrappers(); // Get an object from a tracker runtime. IntPtr trackerObjRaw = MockReferenceTrackerRuntime.CreateTrackerObject(); // Create a managed wrapper for the native object. var trackerObj = (ITrackerObjectWrapper)cw.GetOrCreateObjectForComInstance(trackerObjRaw, CreateObjectFlags.TrackerObject); // Ownership has been transferred to the wrapper. Marshal.Release(trackerObjRaw); var testWrapperIds = new List <int>(); for (int i = 0; i < 1000; ++i) { // Create a native wrapper for the managed object. IntPtr testWrapper = cw.GetOrCreateComInterfaceForObject(new Test(), CreateComInterfaceFlags.TrackerSupport); // Pass the managed object to the native object. int id = trackerObj.AddObjectRef(testWrapper); // Retain the managed object wrapper ptr. testWrapperIds.Add(id); Marshal.Release(testWrapper); } Assert.IsTrue(testWrapperIds.Count <= Test.InstanceCount); GC.Collect(); GC.Collect(); GC.Collect(); GC.Collect(); GC.Collect(); Assert.IsTrue(testWrapperIds.Count <= Test.InstanceCount); // Remove the managed object ref from the native object. foreach (int id in testWrapperIds) { trackerObj.DropObjectRef(id); } testWrapperIds.Clear(); GC.Collect(); GC.Collect(); GC.Collect(); GC.Collect(); GC.Collect(); }
static void ValidateComInterfaceCreationRoundTrip() { Console.WriteLine($"Running {nameof(ValidateComInterfaceCreationRoundTrip)}..."); var testObj = new Test(); var wrappers = new TestComWrappers(); // Allocate a wrapper for the object IntPtr comWrapper = wrappers.GetOrCreateComInterfaceForObject(testObj, CreateComInterfaceFlags.None); Assert.AreNotEqual(IntPtr.Zero, comWrapper); var testObjUnwrapped = wrappers.GetOrCreateObjectForComInstance(comWrapper, CreateObjectFlags.Unwrap); Assert.AreEqual(testObj, testObjUnwrapped); // Release the wrapper int count = Marshal.Release(comWrapper); Assert.AreEqual(0, count); }
static IntPtr CreateWrapper(TestComWrappers cw) { return(cw.GetOrCreateComInterfaceForObject(new Test(), CreateComInterfaceFlags.TrackerSupport)); }