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 ExactSpellingfalse 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.

Unicode

  • Marshalling von Zeichenfolgen

    Der Plattformaufruf kopiert Zeichenfolgen aus dem verwalteten Format (Unicode) in Unicode-Format.

  • Namensübereinstimmung

    Wenn das 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 ExactSpellingfalse 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.

Auto

  • 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);

Siehe auch