public void Initialize(ICallbackable callbackable) { callbackable.Shadow = (IDisposable)this; Type type1 = callbackable.GetType(); List <Type> list; lock (ShadowContainer.typeToShadowTypes) { if (!ShadowContainer.typeToShadowTypes.TryGetValue(type1, out list)) { Type[] local_2 = type1.GetInterfaces(); list = new List <Type>(); list.AddRange((IEnumerable <Type>)local_2); ShadowContainer.typeToShadowTypes.Add(type1, list); foreach (Type item_1 in local_2) { if (ShadowAttribute.Get(item_1) == null) { list.Remove(item_1); } else { foreach (Type item_0 in item_1.GetInterfaces()) { list.Remove(item_0); } } } } } CppObjectShadow cppObjectShadow1 = (CppObjectShadow)null; foreach (Type type2 in list) { CppObjectShadow cppObjectShadow2 = (CppObjectShadow)Activator.CreateInstance(ShadowAttribute.Get(type2).Type); cppObjectShadow2.Initialize(callbackable); if (cppObjectShadow1 == null) { cppObjectShadow1 = cppObjectShadow2; this.guidToShadow.Add(ComObjectShadow.IID_IUnknown, cppObjectShadow1); } this.guidToShadow.Add(Utilities.GetGuidFromType(type2), cppObjectShadow2); foreach (Type type3 in type2.GetInterfaces()) { if (ShadowAttribute.Get(type3) != null) { this.guidToShadow.Add(Utilities.GetGuidFromType(type3), cppObjectShadow2); } } } }
public void Initialize(ICallbackable callbackable) { callbackable.Shadow = this; var type = callbackable.GetType(); List <Type> slimInterfaces; // Cache reflection on COM interface inheritance lock (typeToShadowTypes) { if (!typeToShadowTypes.TryGetValue(type, out slimInterfaces)) { #if BEFORE_NET45 var interfaces = type.GetTypeInfo().GetInterfaces(); #else var interfaces = type.GetTypeInfo().ImplementedInterfaces; #endif slimInterfaces = new List <Type>(); slimInterfaces.AddRange(interfaces); typeToShadowTypes.Add(type, slimInterfaces); // First pass to identify most detailed interfaces foreach (var item in interfaces) { // Only process interfaces that are using shadow var shadowAttribute = ShadowAttribute.Get(item); if (shadowAttribute == null) { slimInterfaces.Remove(item); continue; } // Keep only final interfaces and not intermediate. #if BEFORE_NET45 var inheritList = item.GetTypeInfo().GetInterfaces(); #else var inheritList = item.GetTypeInfo().ImplementedInterfaces; #endif foreach (var inheritInterface in inheritList) { slimInterfaces.Remove(inheritInterface); } } } } CppObjectShadow iunknownShadow = null; // Second pass to instantiate shadow foreach (var item in slimInterfaces) { // Only process interfaces that are using shadow var shadowAttribute = ShadowAttribute.Get(item); // Initialize the shadow with the callback var shadow = (CppObjectShadow)Activator.CreateInstance(shadowAttribute.Type); shadow.Initialize(callbackable); // Take the first shadow as the main IUnknown if (iunknownShadow == null) { iunknownShadow = shadow; // Add IUnknown as a supported interface guidToShadow.Add(ComObjectShadow.IID_IUnknown, iunknownShadow); } guidToShadow.Add(Utilities.GetGuidFromType(item), shadow); // Associate also inherited interface to this shadow #if BEFORE_NET45 var inheritList = item.GetTypeInfo().GetInterfaces(); #else var inheritList = item.GetTypeInfo().ImplementedInterfaces; #endif foreach (var inheritInterface in inheritList) { var inheritShadowAttribute = ShadowAttribute.Get(inheritInterface); if (inheritShadowAttribute == null) { continue; } // Use same shadow as derived guidToShadow.Add(Utilities.GetGuidFromType(inheritInterface), shadow); } } // Precalculate the list of GUID without IUnknown and IInspectable // Used for WinRT int countGuids = 0; foreach (var guidKey in guidToShadow.Keys) { if (guidKey != Utilities.GetGuidFromType(typeof(IInspectable)) && guidKey != Utilities.GetGuidFromType(typeof(IUnknown))) { countGuids++; } } guidPtr = Marshal.AllocHGlobal(Utilities.SizeOf <Guid>() * countGuids); Guids = new IntPtr[countGuids]; int i = 0; unsafe { var pGuid = (Guid *)guidPtr; foreach (var guidKey in guidToShadow.Keys) { if (guidKey == Utilities.GetGuidFromType(typeof(IInspectable)) || guidKey == Utilities.GetGuidFromType(typeof(IUnknown))) { continue; } pGuid[i] = guidKey; // Store the pointer Guids[i] = new IntPtr(pGuid + i); i++; } } }