Skip to content

Conversation

@elinor-fung
Copy link
Member

@elinor-fung elinor-fung commented Sep 28, 2021

Make our char marshaller pin ref/out instead of copy just the char to a local.

ref char parameters are being used as string buffers in parts of the libraries.

Before:

internal static unsafe partial char Method(char p, in char pIn, ref char cRef, out char pOut)
{
    unsafe
    {
        ushort __p_gen_native = default;
        ushort __pIn_gen_native = default;
        ushort __cRef_gen_native = default;
        pOut = default;
        ushort __pOut_gen_native = default;
        char __retVal = default;
        ushort __retVal_gen_native = default;
        //
        // Marshal
        //
        __p_gen_native = p;
        __pIn_gen_native = pIn;
        __cRef_gen_native = cRef;
        __retVal_gen_native = __PInvoke__(__p_gen_native, &__pIn_gen_native, &__cRef_gen_native, &__pOut_gen_native);
        //
        // Unmarshal
        //
        __retVal = (char)__retVal_gen_native;
        pOut = (char)__pOut_gen_native;
        cRef = (char)__cRef_gen_native;
        return __retVal;
    }

    [System.Runtime.InteropServices.DllImportAttribute("DNE", EntryPoint = "Method", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
    extern static unsafe ushort __PInvoke__(ushort p, ushort* pIn, ushort* cRef, ushort* pOut);
}

After:

internal static unsafe partial char Method(char p, in char pIn, ref char cRef, out char pOut)
{
    unsafe
    {
        ushort __pIn_gen_native = default;
        pOut = default;
        char __retVal = default;
        ushort __retVal_gen_native = default;
        //
        // Marshal
        //
        __pIn_gen_native = pIn;
        fixed (char* cRef__pinned = &cRef)
        {
            fixed (char* pOut__pinned = &pOut)
                __retVal_gen_native = __PInvoke__((ushort)p, &__pIn_gen_native, (ushort*)cRef__pinned, (ushort*)pOut__pinned);
        }

        //
        // Unmarshal
        //
        __retVal = (char)__retVal_gen_native;
        return __retVal;
    }

    [System.Runtime.InteropServices.DllImportAttribute("DNE", EntryPoint = "Method", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
    extern static unsafe ushort __PInvoke__(ushort p, ushort* pIn, ushort* cRef, ushort* pOut);
}

cc @AaronRobinsonMSFT @jkoritzinsky

@ghost ghost added the area-Interop-coreclr label Sep 28, 2021
@AaronRobinsonMSFT
Copy link
Member

@elinor-fung The in char pIn is still a by-ref so it should also get the pinned treatment I believe.

@elinor-fung
Copy link
Member Author

I didn't do it for in because one of the tests checks that the value doesn't get updated, but it looks like the test was doing the wrong thing (double-checked built-in). Will update.

@elinor-fung
Copy link
Member Author

Updated. Also added something to the compat doc about in for blittable types and Unicode char.

@elinor-fung elinor-fung merged commit b7283ef into dotnet:feature/use-dllimport-generator Sep 28, 2021
@elinor-fung elinor-fung deleted the pinRefChar branch September 28, 2021 22:13
@ghost ghost locked as resolved and limited conversation to collaborators Nov 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants