-
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
Linear collection marshallers will generate calls to GetUnmanagedValuesDestination for 'out' variables during cleanup in ManagedToUnmanaged #89885
Comments
Tagging subscribers to this area: @dotnet/interop-contrib Issue DetailsAccording to https://github.com/dotnet/runtime/blob/main/docs/design/libraries/LibraryImportGenerator/UserTypeMarshallingV2.md#stateless-unmanaged-managed-1, it is not required to have this method since the value is only marshalled from unmanaged to managed. The unmarshal stage uses GetUnmanagedValuesSource, which cleanup should use as well. The method void MethodOut(
[MarshalUsing(CountElementName = nameof(size))] out StatelessCollection<StatelessType> pOut,
out int size); void global::SharedTypes.ComInterfaces.IStatelessCollectionStatelessElement.MethodOut(out global::SharedTypes.ComInterfaces.StatelessCollection<global::SharedTypes.ComInterfaces.StatelessType> pOut, out int size)
{
var(__this, __vtable_native) = ((System.Runtime.InteropServices.Marshalling.IUnmanagedVirtualMethodTableProvider)this).GetVirtualMethodTableInfoForKey(typeof(global::SharedTypes.ComInterfaces.IStatelessCollectionStatelessElement));
bool __invokeSucceeded = default;
System.Runtime.CompilerServices.Unsafe.SkipInit(out pOut);
System.Runtime.CompilerServices.Unsafe.SkipInit(out size);
nint __pOut_native = default;
int __invokeRetVal = default;
// Setup - Perform required setup.
int __pOut_native__numElements;
System.Runtime.CompilerServices.Unsafe.SkipInit(out __pOut_native__numElements);
try
{
// Pin - Pin data in preparation for calling the P/Invoke.
fixed (int* __size_native = &size)
{
__invokeRetVal = ((delegate* unmanaged[MemberFunction]<void*, nint*, int*, int> )__vtable_native[6])(__this, &__pOut_native, __size_native);
}
__invokeSucceeded = true;
System.GC.KeepAlive(this);
// Unmarshal - Convert native data to managed data.
System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(__invokeRetVal);
__pOut_native__numElements = size;
pOut = global::SharedTypes.ComInterfaces.StatelessCollectionMarshaller<global::SharedTypes.ComInterfaces.StatelessType, nint>.Default.AllocateContainerForManagedElements(__pOut_native, __pOut_native__numElements);
{
System.ReadOnlySpan<nint> __pOut_native__nativeSpan = global::SharedTypes.ComInterfaces.StatelessCollectionMarshaller<global::SharedTypes.ComInterfaces.StatelessType, nint>.Default.GetUnmanagedValuesSource(__pOut_native, __pOut_native__numElements);
System.Span<global::SharedTypes.ComInterfaces.StatelessType> __pOut_native__managedSpan = global::SharedTypes.ComInterfaces.StatelessCollectionMarshaller<global::SharedTypes.ComInterfaces.StatelessType, nint>.Default.GetManagedValuesDestination(pOut);
for (int __i0 = 0; __i0 < __pOut_native__numElements; ++__i0)
{
__pOut_native__managedSpan[__i0] = global::SharedTypes.ComInterfaces.StatelessTypeMarshaller.ConvertToManaged(__pOut_native__nativeSpan[__i0]);
}
}
}
finally
{
if (__invokeSucceeded)
{
// CleanupCalleeAllocated - Perform cleanup of callee allocated resources.
{
// ISSUE HERE
// Should call GetUnmanagedValuesSource
System.ReadOnlySpan<nint> __pOut_native__nativeSpan = global::SharedTypes.ComInterfaces.StatelessCollectionMarshaller<global::SharedTypes.ComInterfaces.StatelessType, nint>.Default.GetUnmanagedValuesDestination(__pOut_native, __pOut_native__numElements);
for (int __i0 = 0; __i0 < __pOut_native__nativeSpan.Length; ++__i0)
{
global::SharedTypes.ComInterfaces.StatelessTypeMarshaller.Free(__pOut_native__nativeSpan[__i0]);
}
}
__pOut_native__numElements = size;
global::SharedTypes.ComInterfaces.StatelessCollectionMarshaller<global::SharedTypes.ComInterfaces.StatelessType, nint>.Default.Free(__pOut_native);
}
}
}
|
According to https://github.com/dotnet/runtime/blob/main/docs/design/libraries/LibraryImportGenerator/UserTypeMarshallingV2.md#stateless-unmanaged-managed-1, it is not required to have this method since the value is only marshalled from unmanaged to managed. The unmarshal stage uses GetUnmanagedValuesSource, which cleanup should use as well.
The method
The text was updated successfully, but these errors were encountered: