-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: Add StringMarshalling property to GeneratedComInterfaceAttribute #84662
Comments
Tagging subscribers to this area: @dotnet/interop-contrib Issue DetailsBackground and motivationGeneratedComInterface does not support string marshalling with a StringMarshalling enum. To match the functionality of LibraryImport, GeneratedComInterface should also allow specifying a StringMarshalling value. This would apply for all methods in the interface, as well as methods on interfaces that inherit from it if the inheriting interfaces do not specify their own StringMarshalling. API Proposalnamespace System.Runtime.InteropServices.Marshalling;
[AttributeUsage(AttributeTargets.Interface)]
public class GeneratedComInterfaceAttribute : Attribute
{
public StringMarshalling StringMarshalling { get; set; }
} API UsageExample from crossgen2: [GeneratedComInterface(StringMarshalling = StringMarshalling.Utf16)]
[Guid("B029E51B-4C55-4fe2-B993-9F7BC1F10DB4")]
internal partial interface ISymNGenWriter2 : ISymNGenWriter
{
void OpenModW(
string wszModule,
string wszObjFile,
out UIntPtr ppmod);
void CloseMod(UIntPtr pmod);
void ModAddSymbols(UIntPtr pmod, [MarshalAs(UnmanagedType.LPArray)] byte[] pbSym, int cb);
void ModAddSecContribEx(
UIntPtr pmod,
ushort isect,
int off,
int cb,
uint dwCharacteristics,
uint dwDataCrc,
uint dwRelocCrc);
void QueryPDBNameExW(
[MarshalUsing(CountElementName = nameof(cchMax))]
char[] pdb,
IntPtr cchMax);
} Alternative DesignsWe could do a per-method string marshalling attribute, or continue using per-parameter MarshalAs / MarshaUsing attributes. RisksThe ComInterfaceGenerator is new, so there aren't risks of regressions or breaking changes. No other risks come to mind.
|
This comment was marked as resolved.
This comment was marked as resolved.
Also, I'm unsure if we want to propagate the setting across inheritance boundaries. While it's likely correct, it goes more towards the "spooky-action-at-a-distance" model that we've been trying to actively avoid with source-generated interop. Also, in the past we've discussed introducing an assembly-level attribute to specify the string marshalling rules, which would then conflict with the inheritance-based model if the base type was in a different assembly. I'd be interested to hear from the rest of the team as well as I might be in the minority here. |
Those are good points, and I think also it could be confusing if we generate shadowing methods for the base interfaces. Maybe it would be best to force StringMarshalling to be the same as the base interface? And if anyone needs different string marshalling than the base, they can use MarshalUsing/MarshalAs. |
Agreed, and we can easily detect that in the analyzer and force propagation of the setting throughout the heirarchy. The gist is specify it once, it must be specified, and match, for everything below. Anything above should be "okay" because we require it if strings are involved so we should be set. It is sane and matches our expectations for being explicit about string encoding. |
Looks good as proposed namespace System.Runtime.InteropServices.Marshalling;
[AttributeUsage(AttributeTargets.Interface)]
public partial class GeneratedComInterfaceAttribute : Attribute
{
public StringMarshalling StringMarshalling { get; set; }
public Type? StringMarshallingCustomType { get; set; }
} |
[like] Aaron Robinson reacted to your message:
…________________________________
From: Jeremy Barton ***@***.***>
Sent: Thursday, April 27, 2023 6:39:11 PM
To: dotnet/runtime ***@***.***>
Cc: Aaron Robinson ***@***.***>; Team mention ***@***.***>
Subject: Re: [dotnet/runtime] [API Proposal]: Add StringMarshalling property to GeneratedComInterfaceAttribute (Issue #84662)
Looks good as proposed
namespace System.Runtime.InteropServices.Marshalling;
[AttributeUsage(AttributeTargets.Interface)]
public partial class GeneratedComInterfaceAttribute : Attribute
{
public StringMarshalling StringMarshalling { get; set; }
public Type StringMarshallingCustomType { get; set; }
}
—
Reply to this email directly, view it on GitHub<#84662 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AHJXMLONHCTZHVRIL4PMNX3XDK4M7ANCNFSM6AAAAAAW23IHRU>.
You are receiving this because you are on a team that was mentioned.Message ID: ***@***.***>
|
[0] Aaron Robinson reacted to your message:
…________________________________
From: Jeremy Barton ***@***.***>
Sent: Thursday, April 27, 2023 6:39:11 PM
To: dotnet/runtime ***@***.***>
Cc: Aaron Robinson ***@***.***>; Team mention ***@***.***>
Subject: Re: [dotnet/runtime] [API Proposal]: Add StringMarshalling property to GeneratedComInterfaceAttribute (Issue #84662)
Looks good as proposed
namespace System.Runtime.InteropServices.Marshalling;
[AttributeUsage(AttributeTargets.Interface)]
public partial class GeneratedComInterfaceAttribute : Attribute
{
public StringMarshalling StringMarshalling { get; set; }
public Type StringMarshallingCustomType { get; set; }
}
—
Reply to this email directly, view it on GitHub<#84662 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AHJXMLONHCTZHVRIL4PMNX3XDK4M7ANCNFSM6AAAAAAW23IHRU>.
You are receiving this because you are on a team that was mentioned.Message ID: ***@***.***>
|
…shallingCustomType (#87065) The generated code is in file scoped classes, so the interface and StringMarshallingCustomType need to be at least internal visibility. These changes warn if that condition isn't met. Originally, I expected to report a diagnostic, but still generate code for the interface. This required some changes to DiagnosticOr<T> to allow it to hold both a diagnostic and a value if the diagnostic didn't cause failure. In the end those changes weren't necessary, but I left them because I can see them being valuable at some point in the future. Completes #84662
Background and motivation
GeneratedComInterface does not support string marshalling with a StringMarshalling enum. To match the functionality of LibraryImport, GeneratedComInterface should also allow specifying a StringMarshalling value and an accompanying StringMarshallingCustomType. This would apply for all methods in the interface, as well as methods on interfaces that inherit from it if the inheriting interfaces do not specify their own StringMarshalling.
API Proposal
API Usage
Example from crossgen2:
Alternative Designs
We could do a per-method string marshalling attribute, or continue using per-parameter MarshalAs / MarshaUsing attributes.
Risks
The ComInterfaceGenerator is new, so there aren't risks of regressions or breaking changes. No other risks come to mind.
Steps
StringMarshalling
field on theGeneratedComInterfaceAttribute
Add basic support for StringMarshalling in GeneratedComInterface #86404StringMarshalling
andStringMarshallingCustomType
as the base interface. [ComInterfaceGenerator] Warn if StringMarshalling doesn't match base and warn if base interface cannot be generated #86467Warn if theWarn if StringMarshallingCustomType is less visible than 'internal' [ComInterfaceGenerator] Warn on visibility of interface and StringMarshallingCustomType #87065StringMarshallingCustomType
is less visible than the interface.The text was updated successfully, but these errors were encountered: