diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs index 79fb7e1982ba9f..45fc359bf6b5f0 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs @@ -389,6 +389,22 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M var virtualMethodIndexData = new VirtualMethodIndexData(index, ImplicitThisParameter: true, direction, true, ExceptionMarshalling.Com); + MarshallingInfo exceptionMarshallingInfo; + + if (generatedComInterfaceAttributeData.ExceptionToUnmanagedMarshaller is null) + { + exceptionMarshallingInfo = new ComExceptionMarshalling(); + } + else + { + exceptionMarshallingInfo = CustomMarshallingInfoHelper.CreateNativeMarshallingInfoForNonSignatureElement( + environment.Compilation.GetTypeByMetadataName(TypeNames.System_Exception), + (INamedTypeSymbol)generatedComInterfaceAttributeData.ExceptionToUnmanagedMarshaller, + generatedComAttribute, + environment.Compilation, + generatorDiagnostics); + } + return new IncrementalMethodStubGenerationContext( signatureContext, containingSyntaxContext, @@ -396,7 +412,7 @@ private static IncrementalMethodStubGenerationContext CalculateStubInformation(M locations, callConv.ToSequenceEqualImmutableArray(SyntaxEquivalentComparer.Instance), virtualMethodIndexData, - new ComExceptionMarshalling(), + exceptionMarshallingInfo, environment.EnvironmentFlags, owningInterface, declaringType, diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceInfo.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceInfo.cs index 9829c914cb11fa..0e5219065c8ab5 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceInfo.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceInfo.cs @@ -94,6 +94,9 @@ public static DiagnosticOrInterfaceInfo From(INamedTypeSymbol symbol, InterfaceD if (!OptionsAreValid(symbol, syntax, interfaceAttributeData, baseAttributeData, out DiagnosticInfo? optionsDiagnostic)) return DiagnosticOrInterfaceInfo.From(optionsDiagnostic); + if (!ExceptionToUnmanagedMarshallerIsValid(syntax, interfaceAttributeData, out DiagnosticInfo? exceptionToUnmanagedMarshallerDiagnostic)) + return DiagnosticOrInterfaceInfo.From(exceptionToUnmanagedMarshallerDiagnostic); + InterfaceInfo info = ( new ComInterfaceInfo( ManagedTypeInfo.CreateTypeInfoForTypeSymbol(symbol), @@ -285,6 +288,34 @@ private static bool OptionsAreValid( return true; } + private static bool ExceptionToUnmanagedMarshallerIsValid( + InterfaceDeclarationSyntax syntax, + GeneratedComInterfaceCompilationData attrSymbolInfo, + [NotNullWhen(false)] out DiagnosticInfo? exceptionToUnmanagedMarshallerDiagnostic) + { + if (attrSymbolInfo.ExceptionToUnmanagedMarshaller is INamedTypeSymbol exceptionToUnmanagedMarshallerType) + { + if (!exceptionToUnmanagedMarshallerType.IsAccessibleFromFileScopedClass(out var details)) + { + exceptionToUnmanagedMarshallerDiagnostic = DiagnosticInfo.Create( + GeneratorDiagnostics.ExceptionToUnmanagedMarshallerNotAccessibleByGeneratedCode, + syntax.Identifier.GetLocation(), + exceptionToUnmanagedMarshallerType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).Replace(TypeNames.GlobalAlias, ""), + details); + return false; + } + } + else if (attrSymbolInfo.ExceptionToUnmanagedMarshaller is not null) + { + exceptionToUnmanagedMarshallerDiagnostic = DiagnosticInfo.Create( + GeneratorDiagnostics.InvalidExceptionToUnmanagedMarshallerType, + syntax.Identifier.GetLocation()); + return false; + } + exceptionToUnmanagedMarshallerDiagnostic = null; + return true; + } + /// /// Returns true if there is 0 or 1 base Com interfaces (i.e. the inheritance is valid), and returns false when there are 2 or more base Com interfaces and sets . /// diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratedComInterfaceAttributeData.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratedComInterfaceAttributeData.cs index b062e249759d07..c07205be2b5edf 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratedComInterfaceAttributeData.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratedComInterfaceAttributeData.cs @@ -35,6 +35,7 @@ public static GeneratedComInterfaceData From(GeneratedComInterfaceCompilationDat internal sealed record GeneratedComInterfaceCompilationData : InteropAttributeCompilationData { public ComInterfaceOptions Options { get; init; } = ComInterfaceOptions.ManagedObjectWrapper | ComInterfaceOptions.ComObjectWrapper; + public ITypeSymbol? ExceptionToUnmanagedMarshaller { get; init; } public static bool TryGetGeneratedComInterfaceAttributeFromInterface(INamedTypeSymbol interfaceSymbol, [NotNullWhen(true)] out AttributeData? generatedComInterfaceAttribute) { @@ -70,6 +71,13 @@ public static GeneratedComInterfaceCompilationData GetDataFromAttribute(Attribut Options = (ComInterfaceOptions)options.Value }; } + if (args.TryGetValue(nameof(ExceptionToUnmanagedMarshaller), out TypedConstant exceptionToUnmanagedMarshaller)) + { + generatedComInterfaceAttributeData = generatedComInterfaceAttributeData with + { + ExceptionToUnmanagedMarshaller = (ITypeSymbol)exceptionToUnmanagedMarshaller.Value + }; + } return generatedComInterfaceAttributeData; } } diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratorDiagnostics.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratorDiagnostics.cs index ca51e30346035a..bc67f140812286 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratorDiagnostics.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/GeneratorDiagnostics.cs @@ -141,6 +141,16 @@ public class Ids DiagnosticSeverity.Error, isEnabledByDefault: true); + /// + public static readonly DiagnosticDescriptor ExceptionToUnmanagedMarshallerNotAccessibleByGeneratedCode = + DiagnosticDescriptorHelper.Create( + Ids.InvalidGeneratedComInterfaceAttributeUsage, + GetResourceString(nameof(SR.InvalidGeneratedComInterfaceAttributeUsageTitle)), + GetResourceString(nameof(SR.ExceptionToUnmanagedMarshallerNotAccessibleByGeneratedCode)), + Category, + DiagnosticSeverity.Error, + isEnabledByDefault: true); + /// public static readonly DiagnosticDescriptor InvalidExceptionMarshallingConfiguration = DiagnosticDescriptorHelper.Create( @@ -152,6 +162,16 @@ public class Ids isEnabledByDefault: true, description: GetResourceString(nameof(SR.InvalidExceptionMarshallingConfigurationDescription))); + /// + public static readonly DiagnosticDescriptor InvalidExceptionToUnmanagedMarshallerType = + DiagnosticDescriptorHelper.Create( + Ids.InvalidGeneratedComInterfaceAttributeUsage, + GetResourceString(nameof(SR.InvalidGeneratedComInterfaceAttributeUsageTitle)), + GetResourceString(nameof(SR.InvalidExceptionToUnmanagedMarshallerType)), + Category, + DiagnosticSeverity.Error, + isEnabledByDefault: true); + /// public static readonly DiagnosticDescriptor ParameterTypeNotSupported = DiagnosticDescriptorHelper.Create( diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/Strings.resx b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/Strings.resx index a90b4dcc9f9124..e333d38603a38b 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/Strings.resx +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/Strings.resx @@ -916,7 +916,13 @@ Specifying 'GeneratedComInterfaceAttribute' on an interface that has a base interface defined in another assembly is not supported + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + Marshalling a generic delegate is not supported. Consider using a function pointer instead. - \ No newline at end of file + diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf index c51ab19853fcf4..ca5736a7ac3338 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.cs.xlf @@ -392,6 +392,11 @@ Zařazovací typ vstupního bodu {0} pro typ {1} musí být typ s nejméně jedním atributem System.Runtime.InteropServices.CustomMarshallerAttribute, který tento typ určuje jako spravovaný typ. + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + Marshalling info was specified for 'ElementIndirectionDepth' {0}, but marshalling info was only needed for {1} level(s) of indirection Informace o zařazování se určily pro ElementIndirectionDepth {0}, ale informace o zařazování byly potřebné pouze pro {1} úrovně indirekce. @@ -617,6 +622,11 @@ Zadaná hodnota není známý příznak výčtu ExceptionMarsnuming. + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + + Classes with 'GeneratedComClassAttribute' must implement one or more interfaces with 'GeneratedComInterfaceAttribute', be marked partial, and be non-generic. Třídy s třídou GeneratedComClassAttribute musí implementovat jedno nebo více rozhraní s „GeneratedComInterfaceAttribute“, být označeny jako částečné a musí být neobecné. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf index b165430bf325a2..0464ceb4f52908 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.de.xlf @@ -392,6 +392,11 @@ Der Marshallertyp "{0}" des Eintrittspunkts für den Typ "{1}" muss ein Typ mit mindestens einem "System.Runtime.InteropServices.CustomMarshallerAttribute" sein, der diesen Typ als verwalteten Typ angibt + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + Marshalling info was specified for 'ElementIndirectionDepth' {0}, but marshalling info was only needed for {1} level(s) of indirection Marshallinginformationen wurden für \"ElementIndirectionDepth\" {0}angegeben. Marshallinginformationen wurden jedoch nur für {1} Dereferenzierungsebene(n) benötigt. @@ -617,6 +622,11 @@ Der angegebene Wert ist kein bekanntes Flag der „ExceptionMarshalling“-Enumeration. + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + + Classes with 'GeneratedComClassAttribute' must implement one or more interfaces with 'GeneratedComInterfaceAttribute', be marked partial, and be non-generic. Klassen mit "GeneratedComClassAttribute" müssen mindestens eine Schnittstelle mit "GeneratedComInterfaceAttribute" implementieren, als "Partiell" gekennzeichnet und nicht generisch sein. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf index 1aca57d4f9ecce..78f6c864bd2c7c 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.es.xlf @@ -392,6 +392,11 @@ El tipo de serializador de punto de entrada "{0}" para el tipo "{1}" debe ser un tipo con al menos un "System.Runtime.InteropServices.CustomMarshallerAttribute" que especifique este tipo como el tipo administrado + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + Marshalling info was specified for 'ElementIndirectionDepth' {0}, but marshalling info was only needed for {1} level(s) of indirection Se especificó información de serialización para “ElementIndirectionDepth” {0}, pero la información de serialización solo era necesaria para {1} niveles de direccionamiento indirecto @@ -617,6 +622,11 @@ El valor proporcionado no es una marca conocida de la enumeración “ExceptionMarshalling”. + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + + Classes with 'GeneratedComClassAttribute' must implement one or more interfaces with 'GeneratedComInterfaceAttribute', be marked partial, and be non-generic. Las clases con "GeneratedComClassAttribute" deben implementar una o varias interfaces con "GeneratedComInterfaceAttribute", marcarse como parciales y no ser genéricas. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf index 271b12e5ab8b6a..851915b7c461f1 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.fr.xlf @@ -392,6 +392,11 @@ Le type de marshaleur de point d’entrée « {0} » pour le type « {1} » doit être un type avec au moins un type « System.Runtime.InteropServices.CustomMarspiaerAttribute » qui spécifie ce type comme type managé + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + Marshalling info was specified for 'ElementIndirectionDepth' {0}, but marshalling info was only needed for {1} level(s) of indirection Des informations de marshaling ont été spécifiées pour « ElementIndirectionDepth » {0}, mais les informations de marshaling étaient uniquement nécessaires pour {1} niveau(s) d’indirection @@ -617,6 +622,11 @@ La valeur fournie n’est pas un indicateur connu de l’énumération « ExceptionMarshalling ». + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + + Classes with 'GeneratedComClassAttribute' must implement one or more interfaces with 'GeneratedComInterfaceAttribute', be marked partial, and be non-generic. Les classes avec 'GeneratedComClassAttribute' doivent implémenter une ou plusieurs interfaces avec 'GeneratedComInterfaceAttribute', être marquées comme partielles et non génériques. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf index e99df5eb1d76fe..270815e73e3d87 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.it.xlf @@ -392,6 +392,11 @@ Il tipo di marshaller del punto di ingresso '{0}' per il tipo '{1}' deve essere un tipo con almeno un elemento 'System.Runtime.InteropServices.CustomMarshallerAttribute' che specifica questo tipo come tipo gestito + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + Marshalling info was specified for 'ElementIndirectionDepth' {0}, but marshalling info was only needed for {1} level(s) of indirection Sono state specificate informazioni di marshalling per l'elemento 'ElementIndirectionDepth' {0}, ma le informazioni di marshalling sono necessarie solo per {1} livello/i di riferimento indiretto @@ -617,6 +622,11 @@ Il valore specificato non è un flag noto dell'enumerazione 'ExceptionMarshalling'. + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + + Classes with 'GeneratedComClassAttribute' must implement one or more interfaces with 'GeneratedComInterfaceAttribute', be marked partial, and be non-generic. Le classi con 'GeneratedComClassAttribute' devono implementare una o più interfacce con 'GeneratedComInterfaceAttribute', essere contrassegnate come parziali e non generiche. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf index 85bf1e1932e365..4cb1edec15b8b2 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ja.xlf @@ -392,6 +392,11 @@ 型 '{1}' 向けのエントリ ポイント マーシャラー型 '{0}' は、この型をマネージド型として指定する 'System.Runtime.InteropServices.CustomMarshallerAttribute' を 1 つ以上持つ型である必要があります + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + Marshalling info was specified for 'ElementIndirectionDepth' {0}, but marshalling info was only needed for {1} level(s) of indirection 'ElementIndirectionDepth' {0} にマーシャリング情報が指定されましたが、マーシャリング情報は間接参照の {1} レベルにのみ必要です @@ -617,6 +622,11 @@ 指定された値は、'ExceptionMarshalling' 列挙型の既知のフラグではありません。 + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + + Classes with 'GeneratedComClassAttribute' must implement one or more interfaces with 'GeneratedComInterfaceAttribute', be marked partial, and be non-generic. 'GeneratedComClassAttribute' を持つクラスは、'GeneratedComInterfaceAttribute' を持つ 1 つ以上のインターフェイスを実装し、partial に設定し、非ジェネリックにする必要があります。 diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf index 1d8d61266fbb84..65e400e79266c6 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ko.xlf @@ -392,6 +392,11 @@ '{1}' 유형의 진입점 마샬러 유형 '{0}'은(는) 이 유형을 관리 유형으로 지정하는 'System.Runtime.InteropServices.CustomMarshallerAttribute'가 하나 이상 있는 유형이어야 합니다. + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + Marshalling info was specified for 'ElementIndirectionDepth' {0}, but marshalling info was only needed for {1} level(s) of indirection 마샬링 정보가 'ElementIndirectionDepth' {0}에 대해 지정되었지만 마샬링 정보는 간접 참조 수준 {1}에만 필요했습니다. @@ -617,6 +622,11 @@ 제공된 값은 'ExceptionMarshalling' 열거형의 알려진 플래그가 아닙니다. + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + + Classes with 'GeneratedComClassAttribute' must implement one or more interfaces with 'GeneratedComInterfaceAttribute', be marked partial, and be non-generic. 'GeneratedComClassAttribute'가 있는 클래스는 'GeneratedComInterfaceAttribute'를 사용하여 인터페이스를 하나 이상 구현하고 'partial'로 표시되어야 하며 제네릭이 아니어야 합니다. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf index 95d2c9fc215466..7f967eef2035ef 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pl.xlf @@ -392,6 +392,11 @@ Typ marshallera punktu wejścia „{0}” dla typu „{1}” musi być typem z co najmniej jednym atrybutem „System.Runtime.InteropServices.CustomMarshaellerAttribute”, który określa ten typ jako typ zarządzany + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + Marshalling info was specified for 'ElementIndirectionDepth' {0}, but marshalling info was only needed for {1} level(s) of indirection Informacje dotyczące skierowania zostały określone dla elementu „ElementIndirectionDepth” {0}, ale informacje dotyczące skierowania były potrzebne tylko dla poziomów pośrednich w liczbie {1} @@ -617,6 +622,11 @@ Podana wartość nie jest znaną flagą wyliczenia „'ExceptionMarshalling”. + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + + Classes with 'GeneratedComClassAttribute' must implement one or more interfaces with 'GeneratedComInterfaceAttribute', be marked partial, and be non-generic. Klasy z atrybutem „GeneratedComClassAttribute” muszą implementować co najmniej jeden interfejs z atrybutem „GeneratedComInterfaceAttribute”, być oznaczone jako częściowe i nie być ogólne. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf index f723b3cf6e3446..6c089e67e988cb 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.pt-BR.xlf @@ -392,6 +392,11 @@ O tipo de empacotador de ponto de entrada '{0}' para o tipo '{1}' deve ser um tipo com pelo menos um 'System.Runtime.InteropServices.CustomMarshallerAttribute' que especifica esse tipo como o tipo gerenciado + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + Marshalling info was specified for 'ElementIndirectionDepth' {0}, but marshalling info was only needed for {1} level(s) of indirection As informações de marshalling foram especificadas para o {0} 'ElementIndirectionDepth', mas as informações de marshalling só eram necessárias para {1} nível(s) de indireção @@ -617,6 +622,11 @@ O valor fornecido não é um sinalizador conhecido da enumeração 'ExceptionMarshalling'. + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + + Classes with 'GeneratedComClassAttribute' must implement one or more interfaces with 'GeneratedComInterfaceAttribute', be marked partial, and be non-generic. As classes com 'GeneratedComClassAttribute' devem implementar uma ou mais interfaces com 'GeneratedComInterfaceAttribute', ser marcadas como parciais e não genéricas. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf index f52b8ace5b2ea0..dfcbf026ca6fa8 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.ru.xlf @@ -392,6 +392,11 @@ Тип маршалера точки входа "{0}" для типа "{1}" должен содержать хотя бы один атрибут "System.Runtime.InteropServices.CustomMarshallerAttribute", указывающий этот тип в качестве управляемого типа + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + Marshalling info was specified for 'ElementIndirectionDepth' {0}, but marshalling info was only needed for {1} level(s) of indirection Для \"ElementIndirectionDepth\" {0} указаны сведения маршализации, но они необходимы только для {1} уровней косвенного обращения @@ -617,6 +622,11 @@ Указанное значение не является известным флагом перечисления ExceptionMarshalling. + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + + Classes with 'GeneratedComClassAttribute' must implement one or more interfaces with 'GeneratedComInterfaceAttribute', be marked partial, and be non-generic. Классы с "GeneratedComClassAttribute" должны реализовывать один или несколько интерфейсов с "GeneratedComInterfaceAttribute", помечаться как частичные и быть неуниверсальными. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf index 9640cf17509152..433862bb328a8c 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.tr.xlf @@ -392,6 +392,11 @@ Tür '{1}' için giriş noktası hazırlayıcı türü '{0}', bu türü yönetilen tür olarak belirten en az bir 'System.Runtime.InteropServices.CustomMarshallerAttribute' türü olmalıdır + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + Marshalling info was specified for 'ElementIndirectionDepth' {0}, but marshalling info was only needed for {1} level(s) of indirection 'ElementIndirectionDepth' {0} için sıralama bilgileri belirtildi, ancak sıralama bilgileri yalnızca {1} yöneltme düzeyi için gerekli @@ -617,6 +622,11 @@ Sağlanan değer bilinen bir 'ExceptionMarshalling' sabit listesi bayrağı değil. + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + + Classes with 'GeneratedComClassAttribute' must implement one or more interfaces with 'GeneratedComInterfaceAttribute', be marked partial, and be non-generic. 'GeneratedComClassAttribute' içeren sınıflar 'GeneratedComInterfaceAttribute' ile bir veya daha fazla arabirim uygulamalı, kısmi olarak işaretlenmeli ve genel olmayan olmalıdır. diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf index 5ea6c89e3c8af7..9e56d56f6d8b53 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hans.xlf @@ -392,6 +392,11 @@ 适用于类型“{1}”的入口点封送处理程序类型“{0}”必须是至少具有一个指定此类型为托管类型的 “System.Runtime.InteropServices.CustomMarshallerAttribute”的类型 + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + Marshalling info was specified for 'ElementIndirectionDepth' {0}, but marshalling info was only needed for {1} level(s) of indirection 为 “ElementIndirectionDepth” {0} 指定了封送信息,但只有间接的 {1} 级别需要封送信息 @@ -617,6 +622,11 @@ 提供的值不是 “ExceptionMarshalling” 枚举的已知标志。 + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + + Classes with 'GeneratedComClassAttribute' must implement one or more interfaces with 'GeneratedComInterfaceAttribute', be marked partial, and be non-generic. 具有“GeneratedComClassAttribute”的类必须执行一个或多个具有“GeneratedComInterfaceAttribute”的接口,并标记为部分和非泛型。 diff --git a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf index f1f937cfb8d218..10d642ed5dacc0 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Common/Resources/xlf/Strings.zh-Hant.xlf @@ -392,6 +392,11 @@ 類型 '{1}' 的進入點封送處理器類型 '{0}' 必須是具有至少一個 'System.Runtime.InteropServices.CustomMarshallerAttribute' 的類型,指定此類型為受控類型 + + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + The type '{0}' specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not accessible by generated code. The type must have at least 'internal' accessibility. {1} + + Marshalling info was specified for 'ElementIndirectionDepth' {0}, but marshalling info was only needed for {1} level(s) of indirection 已為 'ElementIndirectionDepth' {0}指定封送處理資訊,但只有 {1}層級 (間接) 需要封送處理資訊 @@ -617,6 +622,11 @@ 提供的值不是 'ExceptionMarshalling' 列舉的已知旗標。 + + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + The type specified as 'GeneratedComInterfaceAttribute.ExceptionToUnmanagedMarshaller' is not a valid marshaller type. + + Classes with 'GeneratedComClassAttribute' must implement one or more interfaces with 'GeneratedComInterfaceAttribute', be marked partial, and be non-generic. 具有 'GeneratedComClassAttribute' 的類別必須實作一或多個具有 'GeneratedComInterfaceAttribute' 的介面、標示為部份且非泛型。 diff --git a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs index c49c5525d18a1a..e00a6de33c437f 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -394,6 +394,7 @@ public GeneratedComInterfaceAttribute() { } public System.Runtime.InteropServices.Marshalling.ComInterfaceOptions Options { get { throw null; } set { } } public System.Runtime.InteropServices.StringMarshalling StringMarshalling { get { throw null; } set { } } public System.Type? StringMarshallingCustomType { get { throw null; } set { } } + public System.Type? ExceptionToUnmanagedMarshaller { get { throw null; } set { } } } [System.CLSCompliantAttribute(false)] public partial interface IComExposedClass diff --git a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/GeneratedComInterfaceAttribute.cs b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/GeneratedComInterfaceAttribute.cs index 60bc272d09284d..917af533139a8d 100644 --- a/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/GeneratedComInterfaceAttribute.cs +++ b/src/libraries/System.Runtime.InteropServices/src/System/Runtime/InteropServices/Marshalling/GeneratedComInterfaceAttribute.cs @@ -38,5 +38,13 @@ public class GeneratedComInterfaceAttribute : Attribute /// or must be set to . /// public Type? StringMarshallingCustomType { get; set; } + + /// + /// Gets or sets the used to control how exceptions are marshalled for all methods on the interface. + /// + /// + /// If this field is not specified, is used to marshal exceptions. + /// + public Type? ExceptionToUnmanagedMarshaller { get; set; } } } diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/ExceptionToUnmanagedMarshallerTests.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/ExceptionToUnmanagedMarshallerTests.cs new file mode 100644 index 00000000000000..c2032b2c875f8a --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Tests/ExceptionToUnmanagedMarshallerTests.cs @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; +using Xunit; + +namespace ComInterfaceGenerator.Tests +{ + public unsafe partial class ExceptionToUnmanagedMarshallerTests + { + [CustomMarshaller(typeof(Exception), MarshalMode.UnmanagedToManagedOut, typeof(CustomExceptionAsHResultMarshaller))] + public static class CustomExceptionAsHResultMarshaller + { + public static int LastException { get; private set; } + + public static int ConvertToUnmanaged(Exception e) + { + return LastException = ExceptionAsHResultMarshaller.ConvertToUnmanaged(e); + } + } + + [GeneratedComInterface(ExceptionToUnmanagedMarshaller = typeof(CustomExceptionAsHResultMarshaller))] + [Guid("90F3657D-23B7-44C4-85DD-80BD1F5266E7")] + public partial interface ICustomExceptionMarshallerComInterface + { + void ThrowException(); + } + + [GeneratedComClass] + public partial class CustomExceptionMarshallerComClass : ICustomExceptionMarshallerComInterface + { + public void ThrowException() => throw new NotImplementedException(); + } + + [Fact] + public void TestCustomExceptionMarshaller() + { + CustomExceptionMarshallerComClass comObject = new(); + StrategyBasedComWrappers wrappers = new(); + nint nativeUnknown = wrappers.GetOrCreateComInterfaceForObject(comObject, CreateComInterfaceFlags.None); + + ICustomExceptionMarshallerComInterface rcw = (ICustomExceptionMarshallerComInterface)wrappers.GetOrCreateObjectForComInstance(nativeUnknown, CreateObjectFlags.None); + Marshal.Release(nativeUnknown); + + const int E_NOTIMPL = unchecked((int)0x80004001); + Assert.Throws(rcw.ThrowException); + Assert.Equal(E_NOTIMPL, CustomExceptionAsHResultMarshaller.LastException); + } + } +} diff --git a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CompileFails.cs b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CompileFails.cs index d7acb49fd7d819..3e959e4d2ac744 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CompileFails.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/ComInterfaceGenerator.Unit.Tests/CompileFails.cs @@ -866,5 +866,23 @@ public async Task ByRefInVariant_ReportsNotRecommendedDiagnostic() test.DisabledDiagnostics.Remove(GeneratorDiagnostics.Ids.NotRecommendedGeneratedComInterfaceUsage); await test.RunAsync(); } + + [Fact] + public async Task VerifyInvalidExceptionToUnmanagedMarshallerTypeDiagnostic() + { + string code = $$""" + using System.Runtime.InteropServices; + using System.Runtime.InteropServices.Marshalling; + + [GeneratedComInterface(ExceptionToUnmanagedMarshaller = typeof(string[]))] + [Guid("9D3FD745-3C90-4C10-B140-FAFB01E3541D")] + public partial interface {|#0:I|} + { + void Method(); + } + """; + + await VerifyComInterfaceGenerator.VerifySourceGeneratorAsync(code, new DiagnosticResult(GeneratorDiagnostics.InvalidExceptionToUnmanagedMarshallerType).WithLocation(0)); + } } }