Пример 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