protected static T ToShadow <T>(IntPtr thisPtr) where T : CppObjectShadow => CppObjectShadow.ToShadow <T>(thisPtr);
internal 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 NET40 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 NET40 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 NET40 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++; } } }