/// <summary> /// Initializes a new instance of the <see cref="InterfaceMetadata"/> class. /// </summary> /// <param name="type">The interface type.</param> public InterfaceMetadata(Type type) { var attribute = type.GetCustomAttribute(typeof(CrossComInterface), false) as CrossComInterface ?? throw new InvalidOperationException($"Type {type} doesn't have {nameof(CrossComInterface)} attribute."); this.RcwType = attribute.RcwType; this.CcwType = attribute.CcwType; var parent = type.GetInterfaces().OrderBy(t => t.GetInterfaces().Length).LastOrDefault(); var parentVirtualTableSize = 0; if (type != typeof(IUnknown) && parent != null && typeof(IUnknown).IsAssignableFrom(parent)) { parentVirtualTableSize = GetValue(parent).VirtualTableSize; } var delegates = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic).Where(t => typeof(Delegate).IsAssignableFrom(t)); var attributes = delegates.Select(t => new { Delegate = t, Attr = t.GetCustomAttribute(typeof(CrossComMethod), false) as CrossComMethod }) .Where(attr => attr.Attr != null) .OrderBy(attr => attr.Attr !.Order) .ToList(); for (int i = 0; i < attributes.Count; i++) { VirtualMethodMetadata.AddValue(attributes[i].Delegate, i + parentVirtualTableSize); } this.VirtualTableSize = parentVirtualTableSize + attributes.Count; }
public ImportedInterfaceMetadata(Type type) { var attribute = type.GetCustomAttribute(typeof(CrossComInterfaceImport), false) as CrossComInterfaceImport; this.Guid = Guid.Parse(attribute.Guid); this.Implementation = attribute.Implementation; var parent = type.GetInterfaces().OrderBy(t => t.GetInterfaces().Length).LastOrDefault(); var parentVirtualTableSize = 0; if (type != typeof(IUnknown) && parent != null) { parentVirtualTableSize = GetValue(parent).VirtualTableSize; } var delegates = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic).Where(t => typeof(Delegate).IsAssignableFrom(t)); var attributes = delegates.Select(t => new { Delegate = t, Attr = t.GetCustomAttribute(typeof(CrossComMethod), false) as CrossComMethod }) .Where(attr => attr.Attr != null) .OrderBy(attr => attr.Attr.Order) .ToList(); for (int i = 0; i < attributes.Count; i++) { VirtualMethodMetadata.AddValue(attributes[i].Delegate, i + parentVirtualTableSize); } this.VirtualTableSize = parentVirtualTableSize + attributes.Count; }