private void CreateField(TypeInfo type, TypeAttr attr, VarDesc var, ref bool isConversionLoss) { TypeDesc fieldTypeDesc = var.elemdescVar.tdesc; TypeConverter typeConverter = new TypeConverter(m_info, type, fieldTypeDesc, ConversionType.Field); Type fieldType = typeConverter.ConvertedType; string fieldName = type.GetDocumentation(var.memid); FieldBuilder field = m_typeBuilder.DefineField(fieldName, fieldType, FieldAttributes.Public); typeConverter.ApplyAttributes(field); isConversionLoss |= typeConverter.IsConversionLoss; // // Emit ComConversionLossAttribute for fields if necessary // if (typeConverter.IsConversionLoss) { field.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss()); // // Emit Wrn_UnconvertableField warning // m_info.ReportEvent( WarningCode.Wrn_UnconvertableField, Resource.FormatString("Wrn_UnconvertableField", type.GetDocumentation(), fieldName)); } // // Emit TypeLibVarAttribute if necessary // if (var.wVarFlags != 0) { field.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibVar((TypeLibVarFlags)var.wVarFlags)); } }
public override void OnCreate() { string name = ManagedName; if (m_type != null) { return; } TypeInfo typeInfo = RefNonAliasedTypeInfo; using (TypeAttr typeAttr = typeInfo.GetTypeAttr()) { // // Create fields // int cVars = typeAttr.cVars; bool isConversionLoss = false; for (int n = 0; n < cVars; ++n) { using (VarDesc var = typeInfo.GetVarDesc(n)) { CreateField(typeInfo, typeAttr, var, ref isConversionLoss); } } // // Emit StructLayout(LayoutKind.Sequential, Pack=cbAlignment) // m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForStructLayout(LayoutKind.Explicit, typeAttr.cbAlignment, typeAttr.cbSizeInstance)); // // Emit ComConversionLossAttribute if necessary // if (isConversionLoss) { m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss()); } // // Emit SerializableAttribute for /transform:serializablevalueclasses // if ((m_info.Settings.m_flags & TypeLibImporterFlags.SerializableValueClasses) != 0) { m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForSerializable()); } m_type = m_typeBuilder.CreateType(); } }
private void CreateField(TypeInfo type, TypeAttr attr, VarDesc var, ref bool isConversionLoss) { if (IsObjectType(type, var.elemdescVar.tdesc)) { isConversionLoss = true; } else { TypeConverter typeConverter = new TypeConverter(m_info, type, var.elemdescVar.tdesc, ConversionType.Field); Type fieldType = typeConverter.ConvertedType; // TlbImp2 will only skip reference types, instead of skipping every field // Also, TlbImp1 will skip ValueType *, which doesn't make any sense. TlbImp2 will keep ValueType * as IntPtr string fieldName = type.GetDocumentation(var.memid); // Generates the [FieldOffset(0)] layout declarations that approximate unions in managed code FieldBuilder field = m_typeBuilder.DefineField(fieldName, fieldType, FieldAttributes.Public); field.SetCustomAttribute(CustomAttributeHelper.GetBuilderForFieldOffset(0)); typeConverter.ApplyAttributes(field); isConversionLoss |= typeConverter.IsConversionLoss; // // Emit ComConversionLossAttribute for fields if necessary // if (typeConverter.IsConversionLoss) { field.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss()); // // Emit Wrn_UnconvertableField warning // m_info.ReportEvent( WarningCode.Wrn_UnconvertableField, Resource.FormatString("Wrn_UnconvertableField", type.GetDocumentation(), fieldName)); } } }
/// <summary> /// Create the type for coclass /// </summary> public override void OnCreate() { // // Avoid duplicate creation // if (m_type != null) { return; } // // Create constructor // This is created before creating other methods because if anything fails, the constructor would still be valid // Otherwise reflection API will try to create one for us which will have incorrect setting (such as no internalcall flag) CreateConstructor(); bool isConversionLoss = false; TypeInfo typeInfo = RefNonAliasedTypeInfo; if ((m_info.Settings.m_flags & TypeLibImporterFlags.PreventClassMembers) == 0) { using (TypeAttr attr = typeInfo.GetTypeAttr()) { Dictionary <Guid, bool> processedInterfaces = new Dictionary <Guid, bool>(); // Iterate through every interface and override the methods // Process the default interface first for (int m = 0; m < 2; ++m) { int nCount = attr.cImplTypes; for (int n = 0; n < nCount; ++n) { IMPLTYPEFLAGS flags = typeInfo.GetImplTypeFlags(n); bool bDefault = (flags & IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0; bool bSource = (flags & IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0; // Use exclusive or to process just the default interface on the first pass if (bDefault ^ m == 1) { TypeInfo typeImpl = typeInfo.GetRefType(n); using (TypeAttr attrImpl = typeImpl.GetTypeAttr()) { if (attrImpl.Guid == WellKnownGuids.IID_IUnknown || attrImpl.Guid == WellKnownGuids.IID_IDispatch) { continue; } // Skip non-dispatch interfaces that doesn't derive from IUnknown if (!attrImpl.IsDispatch && !ConvCommon.IsDerivedFromIUnknown(typeImpl)) { continue; } // Skip duplicate interfaces in type library // In .IDL you can actually write: // coclass A // { // interface IA; // interface IA; // ... // } // if (!processedInterfaces.ContainsKey(attrImpl.Guid)) { HandleParentInterface(typeImpl, bSource, ref isConversionLoss, bDefault); processedInterfaces.Add(attrImpl.Guid, true); } } } } } } } // // Emit ComConversionLoss attribute if necessary // if (isConversionLoss) { m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComConversionLoss()); } m_type = m_typeBuilder.CreateType(); }
/// <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(); }