Skip to content
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

Handle wrapping COM pointers in managed objects #9816

Closed
JeremyKuhne opened this issue Aug 30, 2023 · 3 comments
Closed

Handle wrapping COM pointers in managed objects #9816

JeremyKuhne opened this issue Aug 30, 2023 · 3 comments

Comments

@JeremyKuhne
Copy link
Member

Built-in COM interop is not available when trimming or AOT are enabled. We need to use ComWrappers in those scenarios. This is important where we currently publicly expose COM RCWs. One concrete example of this is in AxHost. AxHost.GetOcx exposes the ActiveX instance and it is also exposed via the customizable construction virtual AxHost.CreateInstanceCore(Guid clsid).

We need to add a helper in ComHelpers that handles falling back to ComWrappers when necessary. The simple implementation would be something like this:

internal static unsafe partial class ComHelpers
{
    internal static bool BuiltInComSupported { get; }
        = AppContext.TryGetSwitch("System.Runtime.InteropServices.BuiltInComInterop.IsSupported", out bool supported)
            ? supported
            : true;

    public static object GetObjectForIUnknown(IUnknown* unknown)
        => BuiltInComSupported
            ? Marshal.GetObjectForIUnknown((nint)unknown)
            : ComInterfaceMarshaller<object>.ConvertToManaged(unknown).OrThrowIfNull();
}

We should also consider a switch that allows forcing the ComInterfaceMarshaller and potentially picking it by default if the reflection based support for casting to [ComImport] interfaces is enabled. ("System.Runtime.InteropServices.Marshalling.EnableGeneratedComInterfaceComImportInterop" AppContext flag or "EnableGeneratedComInterfaceComImportInterop" in MSBuild)

The only issue with the ComInterfaceMarshaller is that presumes objects are free-threaded. We can deal with this by implementing our own IUnknownStrategy that wraps the GIT much as our AgileComPointer does. This would require deriving from StrategyBasedComWrappers and returning a new instance of the strategy by overriding GetOrCreateIUnknownStrategy().

@JeremyKuhne
Copy link
Member Author

Fyi @jkoritzinsky

@weltkante
Copy link
Contributor

weltkante commented Jan 4, 2024

not sure how much this is related, but there is desire of having AxHost work in trimming/NativeAOT scenarios. I'm currently doing handwritten bindings in #10583 to get the basics working for source generators - but while the ActiveX control itself currently can be (manually) written using COM source generators, WinForms itself (AxHost interaction) needs work done to drop classic COM interop

@JeremyKuhne
Copy link
Member Author

ComHelpers.GetObjectForIUnknown now does this.

@github-actions github-actions bot locked and limited conversation to collaborators Aug 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Archived in project
Development

No branches or pull requests

2 participants