Angeben eines Zeichensatzes

Das DllImportAttribute.CharSet-Feld steuert das Marshalling von Zeichenfolgen und bestimmt, wie Funktionsnamen durch Plattformaufruf in einer DLL gesucht werden. In diesem Abschnitt werden beide Verhaltensweisen beschrieben.

Einige APIs exportieren zwei Versionen von Funktionen, die Zeichenfolgenargumente verwenden: eng (ANSI) und weit (Unicode). Die Win32-API z. B. enthält folgende Einstiegspunktnamen für die MessageBox-Funktion:

  • MessageBoxA

    Stellt eine Einzelbytezeichen-Formatierung (ANSI) bereit, die durch ein an den Einstiegspunktnamen angehängtes "A" gekennzeichnet ist. Aufrufe an MessageBoxA marshallen Zeichenfolgen immer im ANSI-Format, das auf Windows 95- und Windows 98-Plattformen üblich ist.

  • MessageBoxW

    Stellt eine Doppelbytezeichen-Formatierung (Unicode) bereit. Zur Unterscheidung ist ein "W" an den Einstiegspunktnamen angehängt. Aufrufe an MessageBoxW marshallen Zeichenfolgen immer im Unicode-Format, das auf Windows NT-, Windows 2000- und Windows XP-Plattformen üblich ist.

Marshallen von Zeichenfolgen und Namensvergleich

Das CharSet-Feld lässt folgende Werte zu:

CharSet.Ansi (Standardwert)

  • Marshallen von Zeichenfolgen

    Durch Plattformaufruf werden Zeichenfolgen aus dem verwalteten Format (Unicode) ins ANSI-Format gemarshallt.

  • Namensvergleich

    Wenn das DllImportAttribute.ExactSpelling-Feld den Wert true aufweist, also den Standardwert in Visual Basic 2005, sucht der Plattformaufruf nur nach dem angegebenen Namen. Wenn Sie z. B. MessageBox angeben, schlägt die Suche durch den Plattformaufruf fehl, wenn keine exakte Übereinstimmung mit der Schreibweise von MessageBox gefunden werden kann.

    Wenn das ExactSpelling-Feld den Wert false aufweist, also den Standardwert in C++ und C#, wird vom Plattformaufruf zunächst nach dem nicht zerlegten Alias (MessageBox) gesucht. Wird dieser nicht gefunden, wird anschließend nach dem zerlegten Namen (MessageBoxA) gesucht. Beachten Sie, dass das ANSI-Namenvergleichsverhalten nicht mit dem Unicode-Namenvergleichsverhalten übereinstimmt.

CharSet.Unicode

  • Marshallen von Zeichenfolgen

    Durch Plattformaufruf werden Zeichenfolgen aus dem verwalteten Format (Unicode) ins Unicode-Format kopiert.

  • Namensvergleich

    Wenn das ExactSpelling-Feld den Wert true besitzt, also den Standardwert in Visual Basic 2005, sucht der Plattformaufruf nur nach dem angegebenen Namen. Wenn Sie z. B. MessageBox angeben, schlägt die Suche durch den Plattformaufruf fehl, wenn keine exakte Übereinstimmung mit der Schreibweise von MessageBox gefunden werden kann.

    Wenn das ExactSpelling-Feld den Wert false aufweist, also den Standardwert in C++ und C#, wird vom Plattformaufruf zunächst nach dem zerlegten Namen (MessageBoxW) gesucht. Wird dieser nicht gefunden, wird anschließend nach dem nicht zerlegten Alias (MessageBox) gesucht. Beachten Sie, dass das Unicode-Namenvergleichsverhalten nicht mit dem ANSI-Namenvergleichsverhalten übereinstimmt.

CharSet.Auto

  • Abhängig von der Zielplattform wählt der Plattformaufruf zur Laufzeit zwischen ANSI-Format und Unicode-Format aus.

Festlegen eines Zeichensatzes in Visual Basic

Im folgenden Beispiel wird die MessageBox-Funktion dreimal mit jeweils unterschiedlichem Zeichensatzverhalten deklariert. Sie können das Zeichensatzverhalten in Visual Basic festlegen, indem Sie der Deklarationsanweisung das Ansi-Schlüsselwort, das Unicode-Schlüsselwort oder das Auto-Schlüsselwort hinzufügen.

Wenn Sie kein Schlüsselwort für den Zeichensatz festlegen, wie dies in der ersten Deklarationsanweisung der Fall ist, wird für das DllImportAttribute.CharSet-Feld standardmäßig der ANSI-Zeichensatz verwendet. In der zweiten und dritten Anweisung in diesem Beispiel wird mittels eines Schlüsselworts explizit ein Zeichensatz festgelegt.

Imports System.Runtime.InteropServices

Public Class Win32
   Declare Function MessageBoxA Lib "user32.dll"(ByVal hWnd As Integer, _
       ByVal txt As String, ByVal caption As String, _
       ByVal Typ As Integer) As Integer

   Declare Unicode Function MessageBoxW Lib "user32.dll" _
       (ByVal hWnd As Integer, ByVal txt As String, _
        ByVal caption As String, ByVal Typ As Integer) As Integer

   Declare Auto Function MessageBox Lib "user32.dll" _
       (ByVal hWnd As Integer, ByVal txt As String, _
        ByVal caption As String, ByVal Typ As Integer) As Integer
End Class

Festlegen eines Zeichensatzes in C# and C++

Das DllImportAttribute.CharSet-Feld identifiziert den zugrunde liegenden Zeichensatz als ANSI oder Unicode. Der Zeichensatz steuert, wie Zeichenfolgenargumente für die Methode gemarshallt werden sollen. Verwenden Sie eine der folgenden Formen, 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 mit Attributen angezeigt, um den Zeichensatz anzugeben. In der ersten Definition wird durch Auslassen des CharSet-Felds standardmäßig der ANSI-Zeichensatz übernommen.

[DllImport("user32.dll")]
    public static extern int MessageBoxA(int hWnd, String text, 
        String caption, uint type);
[DllImport("user32.dll", CharSet=CharSet.Unicode)]
    public static extern int MessageBoxW(int hWnd, String text, 
        String caption, uint type);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
    public static extern int MessageBox(int hWnd, String text, 
        String caption, uint type);
typedef void* HWND;

//Can use MessageBox or MessageBoxA.
[DllImport("user32")]
extern "C" int MessageBox(HWND hWnd,
                          String* pText,
                          String* pCaption,
                          unsigned int uType);

//Can use MessageBox or MessageBoxW.
[DllImport("user32", CharSet=CharSet::Unicode)]
extern "C" int MessageBoxW(HWND hWnd,
                          String* pText,
                          String* pCaption,
                          unsigned int uType);

//Must use MessageBox.
[DllImport("user32", CharSet=CharSet::Auto)]
extern "C" int MessageBox(HWND hWnd,
                          String* pText,
                          String* pCaption,
                          unsigned int uType);

Siehe auch

Referenz

DllImportAttribute

Konzepte

Erstellen von Prototypen in verwaltetem Code

Beispiele für Plattformaufrufe

Weitere Ressourcen

Marshallen von Daten mit Plattformaufruf