The marshalling code generated for
| [LibraryImport(Interop.Libraries.Advapi32,EntryPoint="LsaLookupNames2",SetLastError=true,StringMarshalling=StringMarshalling.Utf16)] |
| internalstaticpartialuintLsaLookupNames2( |
| SafeLsaPolicyHandlehandle, |
| intflags, |
| intcount, |
| MARSHALLED_UNICODE_STRING[]names, |
| outSafeLsaMemoryHandlereferencedDomains, |
| outSafeLsaMemoryHandlesids |
| ); |
looks like this (the code snippet only shows marshalling
names argument, the remaining arguments omitted for brevity):
// <auto-generated/>unsafepartialclassTest{[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Interop.LibraryImportGenerator","7.0.6.47809")][System.Runtime.CompilerServices.SkipLocalsInitAttribute]internalstaticpartialuintLsaLookupNames2(global::Test.MARSHALLED_UNICODE_STRING[]names){int__lastError;global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native*__names_native=default;uint__retVal;// Setup - Perform required setup.global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<global::Test.MARSHALLED_UNICODE_STRING,global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native>.ManagedToUnmanagedIn__names_native__marshaller=new();try{// Marshal - Convert managed data to native data.global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native*__names_native__stackptr=stackallocglobal::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native[global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<global::Test.MARSHALLED_UNICODE_STRING,global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native>.ManagedToUnmanagedIn.BufferSize];__names_native__marshaller.FromManaged(names,newSystem.Span<global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native>(__names_native__stackptr,global::System.Runtime.InteropServices.Marshalling.ArrayMarshaller<global::Test.MARSHALLED_UNICODE_STRING,global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native>.ManagedToUnmanagedIn.BufferSize));{System.ReadOnlySpan<global::Test.MARSHALLED_UNICODE_STRING>__names_native__managedSpan=__names_native__marshaller.GetManagedValuesSource();System.Span<global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native>__names_native__nativeSpan=__names_native__marshaller.GetUnmanagedValuesDestination();for(int__i0=0;__i0<__names_native__managedSpan.Length;++__i0){__names_native__nativeSpan[__i0]=global::Test.MARSHALLED_UNICODE_STRING.Marshaller.ConvertToUnmanaged(__names_native__managedSpan[__i0]);}}// Pin - Pin data in preparation for calling the P/Invoke.
fixed (void*__names_native__unused=__names_native__marshaller){// PinnedMarshal - Convert managed data to native data that requires the managed data to be pinned.__names_native=__names_native__marshaller.ToUnmanaged();System.Runtime.InteropServices.Marshal.SetLastSystemError(0);__retVal=__PInvoke(__names_native);__lastError=System.Runtime.InteropServices.Marshal.GetLastSystemError();}}finally{// Cleanup - Perform required cleanup.__names_native__marshaller.Free();}System.Runtime.InteropServices.Marshal.SetLastPInvokeError(__lastError);return__retVal;// Local P/Invoke[System.Runtime.InteropServices.DllImportAttribute("Advapi32",EntryPoint="LsaLookupNames2",ExactSpelling=true)]staticexternunsafeuint__PInvoke(global::Test.MARSHALLED_UNICODE_STRING.Marshaller.Native*names);}}Notice that there is no cleanup of the unmanaged array after the PInvoke. Are the unmanaged string copies leaking?
The marshalling code generated for
runtime/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.LsaLookupNames2.cs
Lines 13 to 21 in 0c631ab
namesargument, the remaining arguments omitted for brevity):Notice that there is no cleanup of the unmanaged array after the PInvoke. Are the unmanaged string copies leaking?