docs icon indicating copy to clipboard operation
docs copied to clipboard

Missing EntryPoint with "W" suffix on LibraryImport attribute code sample.

Open yuvsust opened this issue 1 year ago • 1 comments

Describe the issue or suggestion

In the P/Invoke doc (https://learn.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke), the code sample is missing the EntryPoint with the "W" suffix in the LibraryImport attribute. As a result, the code sample is not working and creating a haze for the learners to deal with.

Existing code sample,

using System;
using System.Runtime.InteropServices;

public partial class Program
{
    // Import user32.dll (containing the function we need) and define
    // the method corresponding to the native function.
    [LibraryImport("user32.dll", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)]
    private static partial int MessageBox(IntPtr hWnd, string lpText, string lpCaption, uint uType);

    public static void Main(string[] args)
    {
        // Invoke the function as a regular managed method.
        MessageBox(IntPtr.Zero, "Command-line message box", "Attention!", 0);
    }
}

Updated code sample that will work

using System;
using System.Runtime.InteropServices;

public partial class Program
{
    // Import user32.dll (containing the function we need) and define
    // the method corresponding to the native function.
    [LibraryImport("user32.dll", EntryPoint = "MessageBoxW", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)]
    private static partial int MessageBox(IntPtr hWnd, string lpText, string lpCaption, uint uType);

    public static void Main(string[] args)
    {
        // Invoke the function as a regular managed method.
        MessageBox(IntPtr.Zero, "Command-line message box", "Attention!", 0);
    }
}

I want to contribute to that fix Please review the issue and let me know if I can contribute to this fix. Thanks.

yuvsust avatar May 30 '24 07:05 yuvsust

I can confirm this issue as @yuvsust described. I believe this only arose as a side effect of the positive change to replace uses of DLLImport with LibraryImport a few months ago.

We could choose to have our code sample utilize the EntryPoint named parameter in the LibraryImport attribute:

public partial class Program
{
    // Import user32.dll (containing the function we need) and define
    // the method corresponding to the native function.
    [LibraryImport("user32.dll", EntryPoint = "MessageBoxW", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)]
    private static partial int MessageBox(IntPtr hWnd, string lpText, string lpCaption, uint uType);

    public static void Main(string[] args)
    {
        // Invoke the function as a regular managed method.
        MessageBox(IntPtr.Zero, "Command-line message box", "Attention!", 0);
    }
}

or have them call the MessageBoxW function (instead of the MessageBox function) from user32.dll without adding the EntryPoint named parameter:

public partial class Program
{
    // Import user32.dll (containing the function we need) and define
    // the method corresponding to the native function.
    [LibraryImport("user32.dll", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)]
    private static partial int MessageBoxW(IntPtr hWnd, string lpText, string lpCaption, uint uType);

    public static void Main(string[] args)
    {
        // Invoke the function as a regular managed method.
        MessageBoxW(IntPtr.Zero, "Command-line message box", "Attention!", 0);
    }
}

nlov avatar Oct 08 '24 17:10 nlov

I came across this too, and would be happy to contribute a fix. nlov's second suggestion is what I'd choose, but both look good.

JunganSe avatar May 24 '25 13:05 JunganSe