/// <summary> /// Returns whether the interface supports calling by IDispatch /// </summary> /// <param name="interfaceType">The interface</param> /// <returns>True if the interface supports calling by IDispatch, false otherwise</returns> bool InterfaceSupportsDispatch(Type type) { IConvBase convBase = m_info.LookupType(type); if (convBase == null) { return(false); } if (convBase as IConvInterface != null) { IConvInterface convInterface = convBase as IConvInterface; // dispinterface? if (convInterface.RefTypeInfo.GetTypeAttr().IsDispatch) { return(true); } else { return(ConvCommon.IsDerivedFromIDispatch(convInterface.RefTypeInfo)); } } else if (convBase as IConvClassInterface != null || convBase as IConvEventInterface != null) { return(true); } return(false); }
// Helpers to perform actual definitions for types. public IConvBase GetInterface(TypeInfo type, TypeAttr attr) { IConvInterface convInterface = (IConvInterface)GetTypeRef(ConvType.Interface, type); convInterface.Create(); return(convInterface); }
private readonly TypeInfo m_typeInfo; // Corresponding type info #endregion Fields #region Constructors public ConvCoClassExternal(ConverterInfo info, TypeInfo typeInfo, Type managedType, ConverterAssemblyInfo converterAssemblyInfo) { m_typeInfo = typeInfo; m_managedType = managedType; info.RegisterType(managedType, this); TypeInfo defaultTypeInfo = ConvCommon.GetDefaultInterface(ConvCommon.GetAlias(typeInfo)); if (defaultTypeInfo != null) m_defaultInterface = info.GetTypeRef(ConvType.Interface, defaultTypeInfo) as IConvInterface; }
public ConvClassInterfaceExternal(ConverterInfo info, TypeInfo typeInfo, Type managedType, ConverterAssemblyInfo converterAssemblyInfo) { m_typeInfo = typeInfo; m_managedType = managedType; info.RegisterType(managedType, this); // // Associate the default interface with the class interface // TypeInfo defaultInterfaceTypeInfo; if (converterAssemblyInfo.ClassInterfaceMap.GetExclusiveDefaultInterfaceForCoclass(typeInfo, out defaultInterfaceTypeInfo)) { IConvInterface convInterface = info.GetTypeRef(ConvType.Interface, defaultInterfaceTypeInfo) as IConvInterface; convInterface.AssociateWithExclusiveClassInterface(this); } }
protected override void OnDefineType() { TypeInfo typeInfo = RefNonAliasedTypeInfo; using (TypeAttr attr = typeInfo.GetTypeAttr()) { string name = m_info.GetUniqueManagedName(RefTypeInfo, ConvType.CoClass); // // Collect information for a list of interfaces & event interface types // List <Type> intfList = new List <Type>(); // interface list List <Type> eventIntfList = new List <Type>(); // event interface list TypeInfo defaultInterfaceTypeInfo = null; int nCount = attr.cImplTypes; string sourceInterfaceNames = String.Empty; bool hasDefaultInterface = false; bool implementsIEnumerable = ConvCommon.ExplicitlyImplementsIEnumerable(typeInfo, attr); for (int n = 0; n < nCount; ++n) { IMPLTYPEFLAGS flags = typeInfo.GetImplTypeFlags(n); bool isDefault = (flags & IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0; bool isSource = (flags & IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0; TypeInfo typeImpl = typeInfo.GetRefType(n); using (TypeAttr attrImpl = typeImpl.GetTypeAttr()) { // Skip IUnknown & IDispatch if (attrImpl.Guid == WellKnownGuids.IID_IDispatch || attrImpl.Guid == WellKnownGuids.IID_IUnknown) { continue; } // Skip non-dispatch interfaces that doesn't derive from IUnknown if (!attrImpl.IsDispatch && !ConvCommon.IsDerivedFromIUnknown(typeImpl)) { continue; } IConvInterface convInterface = (IConvInterface)m_info.GetTypeRef(ConvType.Interface, typeImpl); // For source interfaces, try create the event interface // Could be already created if it is the default source interface if (isSource) { convInterface.DefineEventInterface(); } // Use the RealManagedType (avoid getting the class interface) Type typeRef = convInterface.RealManagedType; // Append the source interface name to the list for the ComSourceInterfacesAttribute if (isSource) { string interfaceName; if (convInterface.ConvScope == ConvScope.External) { interfaceName = typeRef.AssemblyQualifiedName + "\0"; } else { interfaceName = typeRef.FullName + "\0"; } // Insert default source interface to the beginning if (isDefault) { sourceInterfaceNames = interfaceName + sourceInterfaceNames; } else { sourceInterfaceNames = sourceInterfaceNames + interfaceName; } } if (isDefault) { // Add the real interface first if (isSource) { // For source interface, use the event interface instead // Insert to the beginning eventIntfList.Insert(0, convInterface.EventInterface.ManagedType); } else { m_defaultInterface = convInterface; // Insert to the beginning intfList.Insert(0, typeRef); hasDefaultInterface = true; defaultInterfaceTypeInfo = typeImpl; } } else { if (isSource) { // For source interface, add the event interface instead eventIntfList.Add(convInterface.EventInterface.ManagedType); } else { if (m_defaultInterface == null) { m_defaultInterface = convInterface; defaultInterfaceTypeInfo = typeImpl; } intfList.Add(typeRef); } } } } // // Get class interface // m_classInterface = m_info.GetTypeRef(ConvType.ClassInterface, RefTypeInfo) as IConvClassInterface; if (m_classInterface == null) { throw new TlbImpInvalidTypeConversionException(RefTypeInfo); } // // Build implemented type list in a specific order // List <Type> implTypeList = new List <Type>(); if (hasDefaultInterface) { implTypeList.Add(intfList[0]); intfList.RemoveAt(0); implTypeList.Add(m_classInterface.ManagedType); } else { implTypeList.Add(m_classInterface.ManagedType); if (intfList.Count > 0) { implTypeList.Add(intfList[0]); intfList.RemoveAt(0); } } if (eventIntfList.Count > 0) { implTypeList.Add(eventIntfList[0]); eventIntfList.RemoveAt(0); } implTypeList.AddRange(intfList); implTypeList.AddRange(eventIntfList); // Check to see if the default interface has a member with a DISPID of DISPID_NEWENUM. if (defaultInterfaceTypeInfo != null) { if (!implementsIEnumerable && ConvCommon.HasNewEnumMember(m_info, defaultInterfaceTypeInfo)) { implTypeList.Add(typeof(System.Collections.IEnumerable)); } } // Check to see if the IEnumerable Custom Value exists on the CoClass if doesn't inherit from IEnumerable yet if (!implTypeList.Contains(typeof(System.Collections.IEnumerable))) { if (ConvCommon.HasForceIEnumerableCustomAttribute(typeInfo)) { implTypeList.Add(typeof(System.Collections.IEnumerable)); } } // Define the type m_typeBuilder = m_info.ModuleBuilder.DefineType(name, TypeAttributes.Public | TypeAttributes.Import, typeof(Object), implTypeList.ToArray()); // Handle [Guid(...)] custom attribute ConvCommon.DefineGuid(RefTypeInfo, RefNonAliasedTypeInfo, m_typeBuilder); // Handle [ClassInterface(ClassInterfaceType.None)] m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForClassInterface(ClassInterfaceType.None)); // Handle [TypeLibType(...)] if evaluate to non-0 using (TypeAttr refTypeAttr = RefTypeInfo.GetTypeAttr()) { if (refTypeAttr.wTypeFlags != 0) { m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType((TypeLibTypeFlags)refTypeAttr.wTypeFlags)); } } // Handle [ComSourceInterfacesAttribute] if (sourceInterfaceNames != String.Empty) { sourceInterfaceNames += "\0"; m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComSourceInterfaces(sourceInterfaceNames)); } // Add to symbol table automatically m_info.AddToSymbolTable(RefTypeInfo, ConvType.CoClass, this); // Register type m_info.RegisterType(m_typeBuilder, this); } }
protected override void OnDefineType() { TypeInfo typeInfo = RefNonAliasedTypeInfo; using (TypeAttr attr = typeInfo.GetTypeAttr()) { string name = m_info.GetUniqueManagedName(RefTypeInfo, ConvType.CoClass); // // Collect information for a list of interfaces & event interface types // var intfList = new List<Type>(); // interface list var eventIntfList = new List<Type>(); // event interface list TypeInfo defaultInterfaceTypeInfo = null; int nCount = attr.cImplTypes; string sourceInterfaceNames = String.Empty; bool hasDefaultInterface = false; bool implementsIEnumerable = ConvCommon.ExplicitlyImplementsIEnumerable(typeInfo, attr); for (int n = 0; n < nCount; ++n) { TypeLibTypes.Interop.IMPLTYPEFLAGS flags = typeInfo.GetImplTypeFlags(n); bool isDefault = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FDEFAULT) != 0; bool isSource = (flags & TypeLibTypes.Interop.IMPLTYPEFLAGS.IMPLTYPEFLAG_FSOURCE) != 0; TypeInfo typeImpl = typeInfo.GetRefType(n); using (TypeAttr attrImpl = typeImpl.GetTypeAttr()) { // Skip IUnknown & IDispatch if (attrImpl.Guid == WellKnownGuids.IID_IDispatch || attrImpl.Guid == WellKnownGuids.IID_IUnknown) continue; // Skip non-dispatch interfaces that doesn't derive from IUnknown if (!attrImpl.IsDispatch && !ConvCommon.IsDerivedFromIUnknown(typeImpl)) continue; IConvInterface convInterface = (IConvInterface)m_info.GetTypeRef(ConvType.Interface, typeImpl); ConvCommon.ThrowIfImplementingExportedClassInterface(RefTypeInfo, convInterface); // For source interfaces, try create the event interface // Could be already created if it is the default source interface if (isSource) { convInterface.DefineEventInterface(); } // Use the RealManagedType (avoid getting the class interface) Type typeRef = convInterface.RealManagedType; // Append the source interface name to the list for the ComSourceInterfacesAttribute if (isSource) { string interfaceName; if (convInterface.ConvScope == ConvScope.External) interfaceName = typeRef.AssemblyQualifiedName + "\0"; else interfaceName = typeRef.FullName + "\0"; // Insert default source interface to the beginning if (isDefault) sourceInterfaceNames = interfaceName + sourceInterfaceNames; else sourceInterfaceNames = sourceInterfaceNames + interfaceName; } if (isDefault) { // Add the real interface first if (isSource) { // For source interface, use the event interface instead // Insert to the beginning eventIntfList.Insert(0, convInterface.EventInterface.ManagedType); } else { m_defaultInterface = convInterface; // Insert to the beginning intfList.Insert(0, typeRef); hasDefaultInterface = true; defaultInterfaceTypeInfo = typeImpl; } } else { if (isSource) { // For source interface, add the event interface instead eventIntfList.Add(convInterface.EventInterface.ManagedType); } else { if (m_defaultInterface == null) { m_defaultInterface = convInterface; defaultInterfaceTypeInfo = typeImpl; } intfList.Add(typeRef); } } } } // // Get class interface // m_classInterface = m_info.GetTypeRef(ConvType.ClassInterface, RefTypeInfo) as IConvClassInterface; if (m_classInterface == null) throw new TlbImpInvalidTypeConversionException(RefTypeInfo); // // Build implemented type list in a specific order // var implTypeList = new List<Type>(); if (hasDefaultInterface) { implTypeList.Add(intfList[0]); intfList.RemoveAt(0); implTypeList.Add(m_classInterface.ManagedType); } else { implTypeList.Add(m_classInterface.ManagedType); if (intfList.Count > 0) { implTypeList.Add(intfList[0]); intfList.RemoveAt(0); } } if (eventIntfList.Count > 0) { implTypeList.Add(eventIntfList[0]); eventIntfList.RemoveAt(0); } implTypeList.AddRange(intfList); implTypeList.AddRange(eventIntfList); // Check to see if the default interface has a member with a DISPID of DISPID_NEWENUM. if (defaultInterfaceTypeInfo != null) if (!implementsIEnumerable && ConvCommon.HasNewEnumMember(m_info, defaultInterfaceTypeInfo, name)) implTypeList.Add(typeof(System.Collections.IEnumerable)); // Check to see if the IEnumerable Custom Value exists on the CoClass if doesn't inherit from IEnumerable yet if (!implTypeList.Contains(typeof(System.Collections.IEnumerable))) { if (ConvCommon.HasForceIEnumerableCustomAttribute(typeInfo)) implTypeList.Add(typeof(System.Collections.IEnumerable)); } // Define the type m_typeBuilder = m_info.ModuleBuilder.DefineType(name, TypeAttributes.Public | TypeAttributes.Import, typeof(Object), implTypeList.ToArray()); // Handle [Guid(...)] custom attribute ConvCommon.DefineGuid(RefTypeInfo, RefNonAliasedTypeInfo, m_typeBuilder); // Handle [ClassInterface(ClassInterfaceType.None)] m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForClassInterface(ClassInterfaceType.None)); // Handle [TypeLibType(...)] if evaluate to non-0 using (TypeAttr refTypeAttr = RefTypeInfo.GetTypeAttr()) { if (refTypeAttr.wTypeFlags != 0) m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForTypeLibType((TypeLibTypeFlags)refTypeAttr.wTypeFlags)); } // Handle [ComSourceInterfacesAttribute] if (sourceInterfaceNames != String.Empty) { sourceInterfaceNames += "\0"; m_typeBuilder.SetCustomAttribute(CustomAttributeHelper.GetBuilderForComSourceInterfaces(sourceInterfaceNames)); } // Add to symbol table automatically m_info.AddToSymbolTable(RefTypeInfo, ConvType.CoClass, this); // Register type m_info.RegisterType(m_typeBuilder, this); } }
public AssemblyBuilder DoProcess( Object typeLib, string asmFilename, TypeLibImporterFlags flags, ITypeLibImporterNotifySink notifySink, byte[] publicKey, StrongNameKeyPair keyPair, string asmNamespace, Version asmVersion, bool isVersion2, bool isPreserveSig, bool isRemoveEnumPrefix) { m_resolver = notifySink; TypeLib tlb = new TypeLib((ITypeLib)typeLib); if (asmNamespace == null) { asmNamespace = tlb.GetDocumentation(); string fileName = System.IO.Path.GetFileNameWithoutExtension(asmFilename); if (fileName != asmNamespace) { asmNamespace = fileName; } // // Support for GUID_ManagedName (for namespace) // string customManagedNamespace = tlb.GetCustData(CustomAttributeGuids.GUID_ManagedName) as string; if (customManagedNamespace != null) { customManagedNamespace = customManagedNamespace.Trim(); if (customManagedNamespace.ToUpper().EndsWith(".DLL")) { customManagedNamespace = customManagedNamespace.Substring(0, customManagedNamespace.Length - 4); } else if (customManagedNamespace.ToUpper().EndsWith(".EXE")) { customManagedNamespace = customManagedNamespace.Substring(0, customManagedNamespace.Length - 4); } asmNamespace = customManagedNamespace; } } // // Check for GUID_ExportedFromComPlus // object value = tlb.GetCustData(CustomAttributeGuids.GUID_ExportedFromComPlus); if (value != null) { // Make this a critical failure, instead of returning null which will be ignored. throw new TlbImpGeneralException(Resource.FormatString("Err_CircularImport", asmNamespace), ErrorCode.Err_CircularImport); } string strModuleName = asmFilename; if (asmFilename.Contains("\\")) { int nIndex; for (nIndex = strModuleName.Length; strModuleName[nIndex - 1] != '\\'; --nIndex) { ; } strModuleName = strModuleName.Substring(nIndex); } // If the version information was not specified, then retrieve it from the typelib. if (asmVersion == null) { using (TypeLibAttr attr = tlb.GetLibAttr()) { asmVersion = new Version(attr.wMajorVerNum, attr.wMinorVerNum, 0, 0); } } // Assembly name should not have .DLL // while module name must contain the .DLL string strAsmName = String.Copy(strModuleName); if (strAsmName.EndsWith(".DLL", StringComparison.InvariantCultureIgnoreCase)) { strAsmName = strAsmName.Substring(0, strAsmName.Length - 4); } AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = strAsmName; assemblyName.SetPublicKey(publicKey); assemblyName.Version = asmVersion; assemblyName.KeyPair = keyPair; m_assemblyBuilder = CreateAssemblyBuilder(assemblyName, tlb, flags); m_moduleBuilder = CreateModuleBuilder(m_assemblyBuilder, strModuleName); // Add a listener for the reflection load only resolve events. AppDomain currentDomain = Thread.GetDomain(); ResolveEventHandler asmResolveHandler = new ResolveEventHandler(ReflectionOnlyResolveAsmEvent); currentDomain.ReflectionOnlyAssemblyResolve += asmResolveHandler; ConverterSettings settings; settings.m_isGenerateClassInterfaces = true; settings.m_namespace = asmNamespace; settings.m_flags = flags; settings.m_isVersion2 = isVersion2; settings.m_isPreserveSig = isPreserveSig; settings.m_isRemoveEnumPrefix = isRemoveEnumPrefix; m_converterInfo = new ConverterInfo(m_moduleBuilder, tlb, m_resolver, settings); // // Generate class interfaces // NOTE: // We have to create class interface ahead of time because of the need to convert default interfaces to // class interfafces. However, this creates another problem that the event interface is always named first // before the other interfaces, because we need to create the type builder for the event interface first // so that we can create a class interface that implement it. But in the previous version of TlbImp, // it doesn't have to do that because it can directly create a typeref with the class interface name, // without actually creating anything like the TypeBuilder. The result is that the name would be different // with interop assemblies generated by old tlbimp in this case. // Given the nature of reflection API, this cannot be easily workarounded unless we switch to metadata APIs. // I believe this is acceptable because this only happens when: // 1. People decide to migrate newer .NET framework // 2. The event interface name conflicts with a normal interface // // In this case the problem can be easily fixed with a global refactoring, so I wouldn't worry about that // if (m_converterInfo.GenerateClassInterfaces) { CreateClassInterfaces(); } // // Generate the remaining types except coclass // Because during creating coclass, we require every type, including all the referenced type to be created // This is a restriction of reflection API that when you override a method in parent interface, the method info // is needed so the type must be already created and loaded // List <TypeInfo> coclassList = new List <TypeInfo>(); int nCount = tlb.GetTypeInfoCount(); for (int n = 0; n < nCount; ++n) { TypeInfo type = null; try { type = tlb.GetTypeInfo(n); string strType = type.GetDocumentation(); TypeInfo typeToProcess; TypeAttr attrToProcess; using (TypeAttr attr = type.GetTypeAttr()) { TYPEKIND kind = attr.typekind; if (kind == TYPEKIND.TKIND_ALIAS) { ConvCommon.ResolveAlias(type, attr.tdescAlias, out typeToProcess, out attrToProcess); if (attrToProcess.typekind == TYPEKIND.TKIND_ALIAS) { continue; } else { // We need to duplicate the definition of the user defined type in the name of the alias kind = attrToProcess.typekind; typeToProcess = type; attrToProcess = attr; } } else { typeToProcess = type; attrToProcess = attr; } switch (kind) { // Process coclass later because of reflection API requirements case TYPEKIND.TKIND_COCLASS: coclassList.Add(typeToProcess); break; case TYPEKIND.TKIND_ENUM: m_converterInfo.GetEnum(typeToProcess, attrToProcess); break; case TYPEKIND.TKIND_DISPATCH: case TYPEKIND.TKIND_INTERFACE: m_converterInfo.GetInterface(typeToProcess, attrToProcess); break; case TYPEKIND.TKIND_MODULE: m_converterInfo.GetModule(typeToProcess, attrToProcess); break; case TYPEKIND.TKIND_RECORD: m_converterInfo.GetStruct(typeToProcess, attrToProcess); break; case TYPEKIND.TKIND_UNION: m_converterInfo.GetUnion(typeToProcess, attrToProcess); break; } m_converterInfo.ReportEvent( MessageCode.Msg_TypeInfoImported, Resource.FormatString("Msg_TypeInfoImported", typeToProcess.GetDocumentation())); } } catch (ReflectionTypeLoadException) { throw; // Fatal failure. Throw } catch (TlbImpResolveRefFailWrapperException) { throw; // Fatal failure. Throw } catch (TlbImpGeneralException) { throw; // Fatal failure. Throw } catch (TypeLoadException) { throw; // TypeLoadException is critical. Throw. } catch (Exception) { } } // Process coclass after processing all the other types foreach (TypeInfo type in coclassList) { using (TypeAttr attr = type.GetTypeAttr()) { try { m_converterInfo.GetCoClass(type, attr); } catch (ReflectionTypeLoadException) { throw; // Fatal failure. Throw } catch (TlbImpResolveRefFailWrapperException) { throw; // Fatal failure. Throw } catch (TlbImpGeneralException) { throw; // Fatal failure. Throw } catch (TypeLoadException) { throw; // TypeLoadException is critical. Throw. } catch (Exception) { } } } // // Build an array of EventItfInfo & generate event provider / event sink helpers // Event.TCEAdapterGenerator eventAdapterGenerator = new Event.TCEAdapterGenerator(); List <Event.EventItfInfo> eventItfList = new List <Event.EventItfInfo>(); foreach (IConvBase symbol in m_converterInfo.GetAllConvBase) { IConvInterface convInterface = symbol as IConvInterface; if (convInterface != null) { if (convInterface.EventInterface != null) { Debug.Assert(convInterface.EventInterface is ConvEventInterfaceLocal); ConvEventInterfaceLocal local = convInterface.EventInterface as ConvEventInterfaceLocal; Type eventInterfaceType = convInterface.EventInterface.ManagedType; // Build EventItfInfo and add to the list Type sourceInterfaceType = convInterface.ManagedType; string sourceInterfaceName = sourceInterfaceType.FullName; Event.EventItfInfo eventItfInfo = new Event.EventItfInfo( eventInterfaceType.FullName, sourceInterfaceName, local.EventProviderName, eventInterfaceType, convInterface.ManagedType); eventItfList.Add(eventItfInfo); } } } eventAdapterGenerator.Process(m_moduleBuilder, eventItfList); return(m_assemblyBuilder); }
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()); }
public ConvEventInterfaceLocal(IConvInterface convInterface, ConverterInfo info) { m_convInterface = convInterface; DefineType(info, convInterface.RefTypeInfo, false); }
/// <summary> /// Check whether the interface, which the type "extendedType" wants to implement, is a class interface /// exported by TlbExp. /// We do not support this scenario, and an exception will be thrown. /// </summary> internal static void ThrowIfImplementingExportedClassInterface( TypeInfo extendedType, IConvInterface parentInterface) { TypeInfo parentType = parentInterface.RefTypeInfo; TypeLib parentTypeLib = parentType.GetContainingTypeLib(); TypeLib thisTypeLib = extendedType.GetContainingTypeLib(); var asmName = parentTypeLib.GetCustData(CustomAttributeGuids.GUID_ExportedFromComPlus) as string; if (asmName != null) { var parentName = parentType.GetCustData(CustomAttributeGuids.GUID_ManagedName) as string; Type parentManagedType = parentInterface.RealManagedType; if (parentName != null && parentManagedType != null && parentManagedType.IsClass) { string msg = Resource.FormatString("Err_ImplementExportedClassInterface", new object[] { extendedType.GetDocumentation(), thisTypeLib.GetDocumentation(), parentType.GetDocumentation(), parentTypeLib.GetDocumentation() }); throw new TlbImpGeneralException(msg, ErrorCode.Err_ImplementExportedClassInterface); } } }
public ConvEventInterfaceLocal(IConvInterface convInterface, ConverterInfo info) { m_convInterface = convInterface; DefineType(info, convInterface.RefTypeInfo, false); }