Поделиться через


Пример MsgBox

В этом примере демонстрируется, как передавать строковые типы по значению в качестве параметров ввода и когда следует использовать поля EntryPoint, CharSet и ExactSpelling.

В примере используются следующие неуправляемые функции, показанные с исходными объявлениями:

  • MessageBox экспортируется из User32.dll.

    int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption,
       UINT uType);  
    

В этом примере класс NativeMethods содержит управляемый прототип для каждой неуправляемой функции, вызываемой классом MsgBoxSample. Управляемые прототипы методов MsgBox, MsgBox2 и MsgBox3 содержат разные объявления для одной и той же неуправляемой функции.

Объявление MsgBox2 приводит к выводу некорректных данных в окне сообщения, поскольку символьный тип, указанный как ANSI, не соответствует точке входа MessageBoxW, которая определяет функцию Юникода. Объявление MsgBox3 приводит к несоответствию между полями EntryPoint, CharSet и ExactSpelling. При вызове MsgBox3 возникает исключение. Подробные сведения об именовании строк и маршалинге имен см. в разделе "Указание набора символов".

Объявление прототипов

private ref class NativeMethods
{
public:
    // Declares managed prototypes for unmanaged functions.
    [DllImport("User32.dll", EntryPoint = "MessageBox",
        CharSet = CharSet::Auto)]
    static int MsgBox(int hWnd, String^ text, String^ caption,
        unsigned int type);

    // Causes incorrect output in the message window.
    [DllImport("User32.dll", EntryPoint = "MessageBoxW",
        CharSet = CharSet::Ansi)]
    static int MsgBox2(int hWnd, String^ text,
        String^ caption, unsigned int type);

    // Causes an exception to be thrown. EntryPoint, CharSet, and
    // ExactSpelling fields are mismatched.
    [DllImport("User32.dll", EntryPoint = "MessageBox",
        CharSet = CharSet::Ansi, ExactSpelling = true)]
    static int MsgBox3(int hWnd, String^ text,
        String^ caption, unsigned int type);
};
internal static class NativeMethods
{
    // Declares managed prototypes for unmanaged functions.
    [DllImport("User32.dll", EntryPoint = "MessageBox",
        CharSet = CharSet.Auto)]
    internal static extern int MsgBox(
        IntPtr hWnd, string lpText, string lpCaption, uint uType);

    // Causes incorrect output in the message window.
    [DllImport("User32.dll", EntryPoint = "MessageBoxW",
        CharSet = CharSet.Ansi)]
    internal static extern int MsgBox2(
        IntPtr hWnd, string lpText, string lpCaption, uint uType);

    // Causes an exception to be thrown. EntryPoint, CharSet, and
    // ExactSpelling fields are mismatched.
    [DllImport("User32.dll", EntryPoint = "MessageBox",
        CharSet = CharSet.Ansi, ExactSpelling = true)]
    internal static extern int MsgBox3(
        IntPtr hWnd, string lpText, string lpCaption, uint uType);
}
Friend Class NativeMethods
    ' Declares managed prototypes for unmanaged functions.
    Friend Declare Auto Function MsgBox Lib "User32.dll" Alias "MessageBox" (
        ByVal hWnd As IntPtr, ByVal lpText As String, ByVal lpCaption As String,
        ByVal uType As UInteger) As Integer

    ' Causes incorrect output in the message window.
    Friend Declare Ansi Function MsgBox2 Lib "User32.dll" Alias "MessageBoxW" (
        ByVal hWnd As IntPtr, ByVal lpText As String, ByVal lpCaption As String,
        ByVal uType As UInteger) As Integer

    ' Causes an exception to be thrown.
    ' ExactSpelling is True by default when Ansi or Unicode is used.
    Friend Declare Ansi Function MsgBox3 Lib "User32.dll" Alias "MessageBox" (
        ByVal hWnd As IntPtr, ByVal lpText As String, ByVal lpCaption As String,
        ByVal uType As UInteger) As Integer
End Class

Вызов функций

public class MsgBoxSample
{
public:
    static void Main()
    {
        NativeMethods::MsgBox(0, "Correct text", "MsgBox Sample", 0);
        NativeMethods::MsgBox2(0, "Incorrect text", "MsgBox Sample", 0);

        try
        {
            NativeMethods::MsgBox3(0, "No such function", "MsgBox Sample", 0);
        }
        catch (EntryPointNotFoundException^)
        {
            Console::WriteLine("EntryPointNotFoundException thrown as expected!");
        }
    }
};
public class MsgBoxSample
{
    public static void Main()
    {
        NativeMethods.MsgBox(0, "Correct text", "MsgBox Sample", 0);
        NativeMethods.MsgBox2(0, "Incorrect text", "MsgBox Sample", 0);

        try
        {
            NativeMethods.MsgBox3(0, "No such function", "MsgBox Sample", 0);
        }
        catch (EntryPointNotFoundException)
        {
            Console.WriteLine($"{nameof(EntryPointNotFoundException)} thrown as expected!");
        }
    }
}
Public Class MsgBoxSample
    Public Shared Sub Main()
        NativeMethods.MsgBox(0, "Correct text", "MsgBox Sample", 0)
        NativeMethods.MsgBox2(0, "Incorrect text", "MsgBox Sample", 0)

        Try
            NativeMethods.MsgBox3(0, "No such function", "MsgBox Sample", 0)
        Catch e As EntryPointNotFoundException
            Console.WriteLine($"{NameOf(EntryPointNotFoundException)} thrown as expected!")
        End Try
    End Sub
End Class

См. также