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

ComInterfaceGenerator does not allocate an array to pass as [Out] parameter in CCW #87845

Closed
jtschuster opened this issue Jun 20, 2023 · 1 comment · Fixed by #89982
Closed

Comments

@jtschuster
Copy link
Member

By value out CCW does not allocate an array to pass to the interface method. Instead it passes a null pointer.

public void ByValueOutParam([MarshalUsing(ConstantElementCount = 10)][Out] string[] value);

Generated:

internal static int ABI_ByValueOutParam(System.Runtime.InteropServices.ComWrappers.ComInterfaceDispatch* __this_native, nint* __value_native)
    {
        global::SharedTypes.ComInterfaces.MarshallingFails.IStringArrayMarshallingFails @this = default;
        string[] value = default;
        int __retVal = default;
        // Setup - Perform required setup.
        int __value_native__numElements;
        System.Runtime.CompilerServices.Unsafe.SkipInit(out __value_native__numElements);
        try
        {
            // Unmarshal - Convert native data to managed data.
            __retVal = 0; // S_OK
            global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<string, nint>.GetManagedValuesDestination(value).Clear();
            @this = System.Runtime.InteropServices.ComWrappers.ComInterfaceDispatch.GetInstance<global::SharedTypes.ComInterfaces.MarshallingFails.IStringArrayMarshallingFails>(__this_native);
            // Call method on null parameter
            @this.ByValueOutParam(value);
            // Marshal - Convert managed data to native data.
            {
                __value_native__numElements = global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<string, nint>.GetManagedValuesDestination(value).Length;
                System.Span<nint> __value_native__nativeSpan = System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref System.Runtime.CompilerServices.Unsafe.AsRef(in global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<string, nint>.GetUnmanagedValuesSource(__value_native, __value_native__numElements).GetPinnableReference()), __value_native__numElements);
                System.Span<string> __value_native__managedSpan = global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<string, nint>.GetManagedValuesDestination(value);
                for (int __i0 = 0; __i0 < __value_native__numElements; ++__i0)
                {
                    nint __value_native__nativeSpan____i0__original = __value_native__nativeSpan[__i0];
                    __value_native__nativeSpan[__i0] = global::SharedTypes.ComInterfaces.MarshallingFails.StringMarshallingFails.ConvertToUnmanaged(__value_native__managedSpan[__i0]);
                }
            }
        }
        catch (System.Exception __exception)
        {
            __retVal = System.Runtime.InteropServices.Marshalling.ExceptionAsHResultMarshaller<int>.ConvertToUnmanaged(__exception);
        }

 

        return __retVal;
    }
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Jun 20, 2023
@ghost
Copy link

ghost commented Jun 20, 2023

Tagging subscribers to this area: @dotnet/interop-contrib
See info in area-owners.md if you want to be subscribed.

Issue Details

By value out CCW does not allocate an array to pass to the interface method. Instead it passes a null pointer.

public void ByValueOutParam([MarshalUsing(ConstantElementCount = 10)][Out] string[] value);

Generated:

internal static int ABI_ByValueOutParam(System.Runtime.InteropServices.ComWrappers.ComInterfaceDispatch* __this_native, nint* __value_native)
    {
        global::SharedTypes.ComInterfaces.MarshallingFails.IStringArrayMarshallingFails @this = default;
        string[] value = default;
        int __retVal = default;
        // Setup - Perform required setup.
        int __value_native__numElements;
        System.Runtime.CompilerServices.Unsafe.SkipInit(out __value_native__numElements);
        try
        {
            // Unmarshal - Convert native data to managed data.
            __retVal = 0; // S_OK
            global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<string, nint>.GetManagedValuesDestination(value).Clear();
            @this = System.Runtime.InteropServices.ComWrappers.ComInterfaceDispatch.GetInstance<global::SharedTypes.ComInterfaces.MarshallingFails.IStringArrayMarshallingFails>(__this_native);
            // Call method on null parameter
            @this.ByValueOutParam(value);
            // Marshal - Convert managed data to native data.
            {
                __value_native__numElements = global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<string, nint>.GetManagedValuesDestination(value).Length;
                System.Span<nint> __value_native__nativeSpan = System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref System.Runtime.CompilerServices.Unsafe.AsRef(in global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<string, nint>.GetUnmanagedValuesSource(__value_native, __value_native__numElements).GetPinnableReference()), __value_native__numElements);
                System.Span<string> __value_native__managedSpan = global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<string, nint>.GetManagedValuesDestination(value);
                for (int __i0 = 0; __i0 < __value_native__numElements; ++__i0)
                {
                    nint __value_native__nativeSpan____i0__original = __value_native__nativeSpan[__i0];
                    __value_native__nativeSpan[__i0] = global::SharedTypes.ComInterfaces.MarshallingFails.StringMarshallingFails.ConvertToUnmanaged(__value_native__managedSpan[__i0]);
                }
            }
        }
        catch (System.Exception __exception)
        {
            __retVal = System.Runtime.InteropServices.Marshalling.ExceptionAsHResultMarshaller<int>.ConvertToUnmanaged(__exception);
        }

 

        return __retVal;
    }
Author: jtschuster
Assignees: -
Labels:

area-System.Runtime.InteropServices

Milestone: -

@jtschuster jtschuster removed the untriaged New issue has not been triaged by the area owner label Jun 20, 2023
@jtschuster jtschuster added this to the 8.0.0 milestone Aug 3, 2023
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Aug 3, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Aug 8, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Sep 8, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant