protected override void OnDefineType() { string classInterfaceName = m_info.GetUniqueManagedName(m_coclassTypeInfo, ConvType.ClassInterface); Type defaultInterfaceType = null; Type defaultSourceInterfaceType = null; m_convInterface = null; m_convSourceInterface = null; // // Convert default interface // if (m_defaultInterfaceTypeInfo != null) { m_convInterface = (IConvInterface)m_info.GetTypeRef(ConvType.Interface, m_defaultInterfaceTypeInfo); // Don't create the interface because we haven't associated the default interface with the class interface yet // We don't want to create anything in the "Define" stage //m_convInterface.Create(); defaultInterfaceType = m_convInterface.ManagedType; } // // Convert default source interface // if (m_defaultSourceInterfaceTypeInfo != null) { m_convSourceInterface = (IConvInterface)m_info.GetTypeRef(ConvType.Interface, m_defaultSourceInterfaceTypeInfo); // Don't create the interface because we haven't associated the default interface with the class interface yet // We don't want to create anything in the "Define" stage // m_convSourceInterface.Create(); Type sourceInterfaceType = m_convSourceInterface.RealManagedType; IConvEventInterface convEventInterface = m_convSourceInterface.DefineEventInterface(); // Don't create the interface because we haven't associated the default interface with the class interface yet // We don't want to create anything in the "Define" stage // convEventInterface.Create(); defaultSourceInterfaceType = m_convSourceInterface.EventInterface.ManagedType; } // // Prepare list of implemented interfaces // List <Type> implTypes = new List <Type>(); if (defaultInterfaceType != null) { implTypes.Add(defaultInterfaceType); } if (defaultSourceInterfaceType != null) { implTypes.Add(defaultSourceInterfaceType); } // Create the class interface m_typeBuilder = m_info.ModuleBuilder.DefineType( classInterfaceName, TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Import, null, implTypes.ToArray()); // Link to it so that ManagedType will return the class interface while GetWrappedInterfaceType will return the // real interface // This must be done before creating the coclass because coclass needs this information // Only do so when the default interface is exclusively belongs to one coclass if (m_convInterface != null && m_isExclusive) { // Check if the default interface -> class interface relationship exists in the default // interface's type lib. That means we only need to check if the default interface and // the coclass are in the same type library. TypeLib typeLib = m_convInterface.RefTypeInfo.GetContainingTypeLib(); Guid libIdOfDefaultInterface; using (TypeLibAttr libAttr = typeLib.GetLibAttr()) { libIdOfDefaultInterface = libAttr.guid; } Guid libIdOfCoclass; TypeLib coclassTypeLib = m_coclassTypeInfo.GetContainingTypeLib(); using (TypeLibAttr libAttr = coclassTypeLib.GetLibAttr()) { libIdOfCoclass = libAttr.guid; } if (libIdOfDefaultInterface.Equals(libIdOfCoclass)) { m_convInterface.AssociateWithExclusiveClassInterface(this as IConvClassInterface); } } // Emit GuidAttribute, which is the same as the default interface, if it exists // If there is no default Interface here, and the coclass implements IDispatch or IUnknown as non-source // interface, we use the IDispatch or IUnknown's guid. if (defaultInterfaceType != null) { ConvCommon.DefineGuid(m_convInterface.RefTypeInfo, m_convInterface.RefNonAliasedTypeInfo, m_typeBuilder); } else { TypeInfo ImplementedIDispatchOrIUnknownTypeInfo = null; using (TypeAttr attr = m_coclassTypeInfo.GetTypeAttr()) { for (int m = 0; m < attr.cImplTypes; ++m) { TypeLibTypes.Interop.IMPLTYPEFLAGS flags = m_coclassTypeInfo.GetImplTypeFlags(m); bool bDefault = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0; bool bSource = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0; TypeInfo typeImpl = m_coclassTypeInfo.GetRefType(m); using (TypeAttr attrImpl = typeImpl.GetTypeAttr()) { if (attrImpl.Guid == WellKnownGuids.IID_IDispatch || attrImpl.Guid == WellKnownGuids.IID_IUnknown) { // If more than one IDispatch or IUnknown exist, we will pick the default one; // If none of them is with the default flag, pick the first one. if (!bSource && (bDefault || ImplementedIDispatchOrIUnknownTypeInfo == null)) { ImplementedIDispatchOrIUnknownTypeInfo = typeImpl; } } } } } if (ImplementedIDispatchOrIUnknownTypeInfo != null) { ConvCommon.DefineGuid(ImplementedIDispatchOrIUnknownTypeInfo, ImplementedIDispatchOrIUnknownTypeInfo, m_typeBuilder); } } // Make sure we know about the class interface before we go to define the coclass in the next statement m_info.RegisterType(m_typeBuilder, this); m_info.AddToSymbolTable(m_coclassTypeInfo, ConvType.ClassInterface, this); // Handle [CoClass(typeof(...))] Type typeRefCoClass = m_info.GetTypeRef(ConvType.CoClass, m_coclassTypeInfo).ManagedType; ConstructorInfo ctorCoClassAttribute = typeof(CoClassAttribute).GetConstructor( new Type[] { typeof(Type) }); // For back compatibility, use full name to create CoClassAttribute, instead of assembly qualified name. CustomAttributeBlobBuilder blobBuilder = new CustomAttributeBlobBuilder(); blobBuilder.AddFixedArg(typeRefCoClass.FullName); m_typeBuilder.SetCustomAttribute(ctorCoClassAttribute, blobBuilder.GetBlob()); }
/// <summary> /// Create the event interface /// </summary> public override void OnCreate() { if (m_type != null) { return; } string name = m_convInterface.ManagedName; m_convInterface.Create(); using (TypeAttr attr = m_convInterface.RefTypeInfo.GetTypeAttr()) { // // Emit attributes // // // Emit [ComEventInterfaceAttribute(...)] // ConstructorInfo ctorComEventInterface = typeof(ComEventInterfaceAttribute).GetConstructor( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(Type), typeof(Type) }, null); // // Build the blob manually before creating the event interface / provider types. // We only need to give the name of the types, in order to simplify creation logic and avoid dependency // CustomAttributeBlobBuilder blobBuilder = new CustomAttributeBlobBuilder(); string eventInterfaceFullyQualifiedName = name; if (m_convInterface.ConvScope == ConvScope.External) { eventInterfaceFullyQualifiedName = m_convInterface.ManagedType.AssemblyQualifiedName; } blobBuilder.AddFixedArg(eventInterfaceFullyQualifiedName); // source interface // Handle event provider name generation collision scenario m_eventProviderName = m_info.GetUniqueManagedName( m_info.GetRecommendedManagedName(m_convInterface.RefTypeInfo, ConvType.Interface, true) + "_EventProvider"); blobBuilder.AddFixedArg(m_eventProviderName); // corresponding event provider m_typeBuilder.SetCustomAttribute(ctorComEventInterface, blobBuilder.GetBlob()); // // Emit ComVisibleAttribute(false) // m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComVisible(false)); // // Emit TypeLibTypeAttribute for TYPEFLAG_FHIDDEN // m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType(TypeLibTypeFlags.FHidden)); bool isConversionLoss = false; // // Verify if the type has any properties // Type interfaceType = m_convInterface.RealManagedType; if (interfaceType.GetProperties().Length > 0) { // Emit a warning and we'll skip the properties m_info.ReportEvent( WarningCode.Wrn_NoPropsInEvents, Resource.FormatString("Wrn_NoPropsInEvents", RefTypeInfo.GetDocumentation())); isConversionLoss = true; } // // Create event interface // InterfaceInfo eventInterfaceInfo = new InterfaceInfo(m_info, m_typeBuilder, false, m_convInterface.RefTypeInfo, attr, false, true); ConvCommon.CreateEventInterfaceCommon(eventInterfaceInfo); isConversionLoss |= eventInterfaceInfo.IsConversionLoss; // // Emit ComConversionLossAttribute if necessary // if (eventInterfaceInfo.IsConversionLoss) { m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss()); } } m_type = m_typeBuilder.CreateType(); }
protected override void OnDefineType() { string classInterfaceName = m_info.GetUniqueManagedName(m_coclassTypeInfo, ConvType.ClassInterface); Type defaultInterfaceType = null; Type defaultSourceInterfaceType = null; m_convInterface = null; m_convSourceInterface = null; // // Convert default interface // if (m_defaultInterfaceTypeInfo != null) { m_convInterface = (IConvInterface)m_info.GetTypeRef(ConvType.Interface, m_defaultInterfaceTypeInfo); // Don't create the interface because we haven't associated the default interface with the class interface yet // We don't want to create anything in the "Define" stage //m_convInterface.Create(); defaultInterfaceType = m_convInterface.ManagedType; } // // Convert default source interface // if (m_defaultSourceInterfaceTypeInfo != null) { m_convSourceInterface = (IConvInterface)m_info.GetTypeRef(ConvType.Interface, m_defaultSourceInterfaceTypeInfo); // Don't create the interface because we haven't associated the default interface with the class interface yet // We don't want to create anything in the "Define" stage // m_convSourceInterface.Create(); Type sourceInterfaceType = m_convSourceInterface.RealManagedType; IConvEventInterface convEventInterface = m_convSourceInterface.DefineEventInterface(); // Don't create the interface because we haven't associated the default interface with the class interface yet // We don't want to create anything in the "Define" stage // convEventInterface.Create(); defaultSourceInterfaceType = m_convSourceInterface.EventInterface.ManagedType; } // // Prepare list of implemented interfaces // var implTypes = new List<Type>(); if (defaultInterfaceType != null) implTypes.Add(defaultInterfaceType); if (defaultSourceInterfaceType != null) implTypes.Add(defaultSourceInterfaceType); // Create the class interface m_typeBuilder = m_info.ModuleBuilder.DefineType( classInterfaceName, TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Import, null, implTypes.ToArray()); // Link to it so that ManagedType will return the class interface while GetWrappedInterfaceType will return the // real interface // This must be done before creating the coclass because coclass needs this information // Only do so when the default interface is exclusively belongs to one coclass if (m_convInterface != null && m_isExclusive) { // Check if the default interface -> class interface relationship exists in the default // interface's type lib. That means we only need to check if the default interface and // the coclass are in the same type library. TypeLib typeLib = m_convInterface.RefTypeInfo.GetContainingTypeLib(); Guid libIdOfDefaultInterface; using (TypeLibAttr libAttr = typeLib.GetLibAttr()) { libIdOfDefaultInterface = libAttr.guid; } Guid libIdOfCoclass; TypeLib coclassTypeLib = m_coclassTypeInfo.GetContainingTypeLib(); using (TypeLibAttr libAttr = coclassTypeLib.GetLibAttr()) { libIdOfCoclass = libAttr.guid; } if (libIdOfDefaultInterface.Equals(libIdOfCoclass)) { m_convInterface.AssociateWithExclusiveClassInterface(this as IConvClassInterface); } } // Emit GuidAttribute, which is the same as the default interface, if it exists // If there is no default Interface here, and the coclass implements IDispatch or IUnknown as non-source // interface, we use the IDispatch or IUnknown's guid. if (defaultInterfaceType != null) { ConvCommon.DefineGuid(m_convInterface.RefTypeInfo, m_convInterface.RefNonAliasedTypeInfo, m_typeBuilder); } else { TypeInfo ImplementedIDispatchOrIUnknownTypeInfo = null; using (TypeAttr attr = m_coclassTypeInfo.GetTypeAttr()) { for (int m = 0; m < attr.cImplTypes; ++m) { TypeLibTypes.Interop.IMPLTYPEFLAGS flags = m_coclassTypeInfo.GetImplTypeFlags(m); bool bDefault = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0; bool bSource = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0; TypeInfo typeImpl = m_coclassTypeInfo.GetRefType(m); using (TypeAttr attrImpl = typeImpl.GetTypeAttr()) { if (attrImpl.Guid == WellKnownGuids.IID_IDispatch || attrImpl.Guid == WellKnownGuids.IID_IUnknown) { // If more than one IDispatch or IUnknown exist, we will pick the default one; // If none of them is with the default flag, pick the first one. if (!bSource && (bDefault || ImplementedIDispatchOrIUnknownTypeInfo == null)) { ImplementedIDispatchOrIUnknownTypeInfo = typeImpl; } } } } } if (ImplementedIDispatchOrIUnknownTypeInfo != null) { ConvCommon.DefineGuid(ImplementedIDispatchOrIUnknownTypeInfo, ImplementedIDispatchOrIUnknownTypeInfo, m_typeBuilder); } } // Make sure we know about the class interface before we go to define the coclass in the next statement m_info.RegisterType(m_typeBuilder, this); m_info.AddToSymbolTable(m_coclassTypeInfo, ConvType.ClassInterface, this); // Handle [CoClass(typeof(...))] Type typeRefCoClass = m_info.GetTypeRef(ConvType.CoClass, m_coclassTypeInfo).ManagedType; ConstructorInfo ctorCoClassAttribute = typeof(CoClassAttribute).GetConstructor( new Type[] { typeof(Type) }); // For back compatibility, use full name to create CoClassAttribute, instead of assembly qualified name. CustomAttributeBlobBuilder blobBuilder = new CustomAttributeBlobBuilder(); blobBuilder.AddFixedArg(typeRefCoClass.FullName); m_typeBuilder.SetCustomAttribute(ctorCoClassAttribute, blobBuilder.GetBlob()); }
/// <summary> /// Create the event interface /// </summary> public override void OnCreate() { if (m_type != null) return; string name = m_convInterface.ManagedName; m_convInterface.Create(); using (TypeAttr attr = m_convInterface.RefTypeInfo.GetTypeAttr()) { // // Emit attributes // // // Emit [ComEventInterfaceAttribute(...)] // ConstructorInfo ctorComEventInterface = typeof(ComEventInterfaceAttribute).GetConstructor( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(Type), typeof(Type) }, null); // // Build the blob manually before creating the event interface / provider types. // We only need to give the name of the types, in order to simplify creation logic and avoid dependency // CustomAttributeBlobBuilder blobBuilder = new CustomAttributeBlobBuilder(); string eventInterfaceFullyQualifiedName = name; if (m_convInterface.ConvScope == ConvScope.External) eventInterfaceFullyQualifiedName = m_convInterface.ManagedType.AssemblyQualifiedName; blobBuilder.AddFixedArg(eventInterfaceFullyQualifiedName); // source interface // Handle event provider name generation collision scenario m_eventProviderName = m_info.GetUniqueManagedName( m_info.GetRecommendedManagedName(m_convInterface.RefTypeInfo, ConvType.Interface, true) + "_EventProvider"); blobBuilder.AddFixedArg(m_eventProviderName); // corresponding event provider m_typeBuilder.SetCustomAttribute(ctorComEventInterface, blobBuilder.GetBlob()); // // Emit ComVisibleAttribute(false) // m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComVisible(false)); // // Emit TypeLibTypeAttribute for TYPEFLAG_FHIDDEN // m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType(TypeLibTypeFlags.FHidden)); bool isConversionLoss = false; // // Verify if the type has any properties // Type interfaceType = m_convInterface.RealManagedType; if (interfaceType.GetProperties().Length > 0) { // Emit a warning and we'll skip the properties m_info.ReportEvent( WarningCode.Wrn_NoPropsInEvents, Resource.FormatString("Wrn_NoPropsInEvents", RefTypeInfo.GetDocumentation())); isConversionLoss = true; } // // Create event interface // InterfaceInfo eventInterfaceInfo = new InterfaceInfo(m_info, m_typeBuilder, false, m_convInterface.RefTypeInfo, attr, false, true); ConvCommon.CreateEventInterfaceCommon(eventInterfaceInfo); isConversionLoss |= eventInterfaceInfo.IsConversionLoss; // // Emit ComConversionLossAttribute if necessary // if (eventInterfaceInfo.IsConversionLoss) { m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss()); } } m_type = m_typeBuilder.CreateType(); }