Angeben eines Zeichensatzes
Das DllImportAttribute.CharSet-Feld steuert das Marshallen von Zeichenfolgen und bestimmt, auf welche Weise Plattformaufrufe Funktionsnamen in einer DLL finden. In diesem Abschnitt werden beide Verhaltensweisen beschrieben.
Einige APIs exportieren zwei Versionen von Funktionen, die Zeichenfolgenargumente verwenden: schmal (ANSI) und breit (Unicode). Die Windows-API enthält z.B. die folgenden Einstiegspunktnamen für die MessageBox-Funktion:
MessageBoxA
Stellt einen 1-Byte-Zeichensatz im ANSI-Format zur Verfügung, der durch ein zum Namen des Einstiegspunkts hinzugefügten „A“ unterschieden wird. Aufrufe von MessageBoxA marshallen Zeichenfolgen immer im ANSI-Format.
MessageBoxW
Stellt einen 2-Byte-Zeichensatz im Unicode-Format zur Verfügung, der durch ein zum Namen des Einstiegspunkts hinzugefügten „W“ unterschieden wird. Aufrufe von MessageBoxW marshallen Zeichenfolgen immer im Unicode-Format.
Marshallen von Zeichenfolgen und Namensabgleich
Das Feld CharSet
akzeptiert die folgenden Werte:
Ansi (Standardwert)
Marshalling von Zeichenfolgen
Plattformaufruf marshallt Zeichenfolgen aus dem verwalteten Format (Unicode) in das ANSI-Format.
Namensübereinstimmung
Wenn das DllImportAttribute.ExactSpelling-Feld
true
entspricht, wie es standardmäßig in Visual Basic der Fall ist, sucht der Plattformaufruf nur nach dem von Ihnen angegebenen Namen. Wenn Sie z.B. MessageBox angeben, sucht der Plattformaufruf nach MessageBox und schlägt fehl, wenn er die exakte Schreibweise nicht finden kann.Wenn das Feld
ExactSpelling
false
ist, wie es standardmäßig in C++ und C# der Fall ist, sucht der Plattformaufruf zunächst nach dem unbeschädigten Alias (MessageBox) und dann nach dem beschädigten Namen (MessageBoxA), wenn der unbeschädigten Alias nicht gefunden wird. Beachten Sie, dass die Namensübereinstimmung des ANSI-Verhaltens sich von der Namensübereinstimmung des Unicode-Verhaltens unterscheidet.
Marshalling von Zeichenfolgen
Der Plattformaufruf kopiert Zeichenfolgen aus dem verwalteten Format (Unicode) in Unicode-Format.
Namensübereinstimmung
Wenn das
ExactSpelling
-Feldtrue
entspricht, wie es standardmäßig in Visual Basic der Fall ist, sucht der Plattformaufruf nur nach dem von Ihnen angegebenen Namen. Wenn Sie z.B. MessageBox angeben, sucht der Plattformaufruf nach MessageBox und schlägt fehl, wenn er die exakte Schreibweise nicht finden kann.Wenn das Feld
ExactSpelling
false
ist, wie es standardmäßig in C++ und C# der Fall ist, sucht der Plattformaufruf zunächst nach dem beschädigten Namen (MessageBoxW) und dann nach dem unbeschädigten Alias (MessageBox), wenn der beschädigte Alias nicht gefunden wird. Beachten Sie, dass das Verhalten der Namensübereinstimmung von Unicode sich vom Verhalten der Namensübereinstimmung von ANSI unterscheidet.
- Der Plattformaufruf basierend auf der Zielplattform zur Laufzeit wählt zwischen ANSI- und Unicode-Formaten.
Festlegen eines Zeichensatzes in Visual Basic
Sie können das Verhalten des Zeichensatzes in Visual Basic angeben, indem Sie die Schlüsselwörter Ansi
, Unicode
oder Auto
zur Deklarationsanweisung hinzufügen. Wenn Sie das Zeichensatzschlüsselwort weglassen, wird auf das DllImportAttribute.CharSet-Feld standardmäßig der ANSI-Zeichensatz angewendet.
Das folgende Beispiel deklariert die MessageBox-Funktion dreimal, wobei der Zeichensatz sich jedes Mal unterschiedlich verhält. Die erste Anweisung lässt das Zeichensatzschlüsselwort aus, sodass ANSI standardmäßig als Zeichensatz verwendet wird. Die zweite und dritte Anweisung geben einen Zeichensatz explizit mit einem Schlüsselwort an.
Friend Class NativeMethods
Friend Declare Function MessageBoxA Lib "user32.dll" (
ByVal hWnd As IntPtr,
ByVal lpText As String,
ByVal lpCaption As String,
ByVal uType As UInteger) As Integer
Friend Declare Unicode Function MessageBoxW Lib "user32.dll" (
ByVal hWnd As IntPtr,
ByVal lpText As String,
ByVal lpCaption As String,
ByVal uType As UInteger) As Integer
Friend Declare Auto Function MessageBox Lib "user32.dll" (
ByVal hWnd As IntPtr,
ByVal lpText As String,
ByVal lpCaption As String,
ByVal uType As UInteger) As Integer
End Class
Festlegen eines Zeichensatzes in C# und C++
Das DllImportAttribute.CharSet-Feld identifiziert den zugrunde liegenden Zeichensatz als ANSI oder Unicode. Der Zeichensatz steuert, wie die Zeichenfolgenargumente für eine Methode gemarshallt werden sollen. Verwenden Sie eines der folgenden Formate, um den Zeichensatz anzugeben:
[DllImport("DllName", CharSet = CharSet.Ansi)]
[DllImport("DllName", CharSet = CharSet.Unicode)]
[DllImport("DllName", CharSet = CharSet.Auto)]
[DllImport("DllName", CharSet = CharSet::Ansi)]
[DllImport("DllName", CharSet = CharSet::Unicode)]
[DllImport("DllName", CharSet = CharSet::Auto)]
Im folgenden Beispiel werden drei verwaltete Definitionen der MessageBox-Funktion angezeigt, die einen Zeichensatz anzeigen. Durch die Auslassung wird das Feld CharSet
in der ersten Definition standardmäßig in ANSI-Zeichensatz verwandelt.
using System;
using System.Runtime.InteropServices;
internal static class NativeMethods
{
[DllImport("user32.dll")]
internal static extern int MessageBoxA(
IntPtr hWnd, string lpText, string lpCaption, uint uType);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
internal static extern int MessageBoxW(
IntPtr hWnd, string lpText, string lpCaption, uint uType);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern int MessageBox(
IntPtr hWnd, string lpText, string lpCaption, uint uType);
}
typedef void* HWND;
// Can use MessageBox or MessageBoxA.
[DllImport("user32")]
extern "C" int MessageBox(
HWND hWnd, String* lpText, String* lpCaption, unsigned int uType);
// Can use MessageBox or MessageBoxW.
[DllImport("user32", CharSet = CharSet::Unicode)]
extern "C" int MessageBoxW(
HWND hWnd, String* lpText, String* lpCaption, unsigned int uType);
// Must use MessageBox.
[DllImport("user32", CharSet = CharSet::Auto)]
extern "C" int MessageBox(
HWND hWnd, String* lpText, String* lpCaption, unsigned int uType);