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 PreserveSig=false #323

Merged

Conversation

elinor-fung
Copy link
Member

@elinor-fung elinor-fung commented Nov 9, 2020

  • Add marshaller for checking HR and throwing on errror
  • Handle transforming return value to last out param

cc @AaronRobinsonMSFT @jkoritzinsky

No return value
public static partial void NoReturnValue(int i)
{
    unsafe
    {
        int __invokeRetVal = default;
        //
        // Invoke
        //
        __invokeRetVal = NoReturnValue__PInvoke__(i);
        //
        // Unmarshal
        //
        System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(__invokeRetVal);
    }
}

[System.Runtime.InteropServices.DllImportAttribute("NativeExportsNE", EntryPoint = "hresult_return")]
extern private static unsafe int NoReturnValue__PInvoke__(int i);
int as return
public static partial int Int_AsReturn(int i)
{
    unsafe
    {
        int __retVal = default;
        int __invokeRetVal = default;
        //
        // Invoke
        //
        __invokeRetVal = Int_AsReturn__PInvoke__(i, &__retVal);
        //
        // Unmarshal
        //
        System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(__invokeRetVal);
        return __retVal;
    }
}

[System.Runtime.InteropServices.DllImportAttribute("NativeExportsNE", EntryPoint = "hresult_out_int")]
extern private static unsafe int Int_AsReturn__PInvoke__(int i, int *__retVal);
UTF-16 string as return
public static partial string String_AsReturn(int i)
{
    unsafe
    {
        string __retVal = default;
        ushort *__retVal_gen_native = default;
        int __invokeRetVal = default;
        try
        {
            //
            // Invoke
            //
            __invokeRetVal = String_AsReturn__PInvoke__(i, &__retVal_gen_native);
            //
            // Unmarshal
            //
            System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(__invokeRetVal);
            __retVal = __retVal_gen_native == null ? null : new string ((char *)__retVal_gen_native);
        }
        finally
        {
            //
            // Cleanup
            //
            System.Runtime.InteropServices.Marshal.FreeCoTaskMem((System.IntPtr)__retVal_gen_native);
        }

        return __retVal;
    }
}

[System.Runtime.InteropServices.DllImportAttribute("NativeExportsNE", EntryPoint = "hresult_out_ushort_string")]
extern private static unsafe int String_AsReturn__PInvoke__(int i, ushort **__retVal);
int array as return
public static partial int[] IntArray_AsReturn(int i)
{
    unsafe
    {
        int[] __retVal = default;
        int *__retVal_gen_native = default;
        int __invokeRetVal = default;
        try
        {
            //
            // Invoke
            //
            __invokeRetVal = IntArray_AsReturn__PInvoke__(i, &__retVal_gen_native);
            //
            // Unmarshal
            //
            System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(__invokeRetVal);
            if (__retVal_gen_native != null)
            {
                __retVal = new int[4];
                new System.Span<int>(__retVal_gen_native, __retVal.Length).CopyTo(__retVal);
            }
            else
                __retVal = null;
        }
        finally
        {
            //
            // Cleanup
            //
            System.Runtime.InteropServices.Marshal.FreeCoTaskMem((System.IntPtr)__retVal_gen_native);
        }

        return __retVal;
    }
}

[System.Runtime.InteropServices.DllImportAttribute("NativeExportsNE", EntryPoint = "hresult_out_int_array")]
extern private static unsafe int IntArray_AsReturn__PInvoke__(int i, int **__retVal);
SafeHandle as return
public static partial global::DllImportGenerator.IntegrationTests.NativeExportsNE.PreserveSig.DummySafeHandle SafeHandle_AsReturn(int hr)
{
    unsafe
    {
        global::DllImportGenerator.IntegrationTests.NativeExportsNE.PreserveSig.DummySafeHandle __retVal = default;
        global::System.IntPtr __retVal_gen_native = default;
        int __invokeRetVal = default;
        //
        // Setup
        //
        __retVal = System.Runtime.InteropServices.MarshalEx.CreateSafeHandle<global::DllImportGenerator.IntegrationTests.NativeExportsNE.PreserveSig.DummySafeHandle>();
        try
        {
            //
            // Invoke
            //
            __invokeRetVal = SafeHandle_AsReturn__PInvoke__(hr, &__retVal_gen_native);
            //
            // Unmarshal
            //
            System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(__invokeRetVal);
        }
        finally
        {
            //
            // GuaranteedUnmarshal
            //
            System.Runtime.InteropServices.MarshalEx.SetHandle(__retVal, __retVal_gen_native);
        }

        return __retVal;
    }
}

[System.Runtime.InteropServices.DllImportAttribute("NativeExportsNE", EntryPoint = "hresult_out_handle")]
extern private static unsafe int SafeHandle_AsReturn__PInvoke__(int hr, global::System.IntPtr*__retVal);

@elinor-fung elinor-fung added the area-DllImportGenerator Source Generated stubs for P/Invokes in C# label Nov 9, 2020
@jkoritzinsky
Copy link
Member

Now that we're adding tests that throw exceptions, we should make sure that we don't forget to add the cleanup exception handling to the stubs.

@elinor-fung elinor-fung merged commit 4562fa7 into dotnet:feature/DllImportGenerator Nov 14, 2020
@elinor-fung elinor-fung deleted the preserveSig branch November 14, 2020 06:14
jkoritzinsky pushed a commit to jkoritzinsky/runtime that referenced this pull request Sep 20, 2021
* Handle PreserveSig=false
* Flag SetLastError=true as unsupported until we add support for it
* Add try-finally to generated code
* Update doc

Commit migrated from dotnet/runtimelab@4562fa7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-DllImportGenerator Source Generated stubs for P/Invokes in C#
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants