Udostępnij przez


Określanie zestawu znaków

Pole DllImportAttribute.CharSet steruje marshalingiem ciągów i określa sposób wywoływania przez platformę nazw funkcji w bibliotece DLL. W tym temacie opisano oba zachowania.

Niektóre interfejsy API eksportują dwie wersje funkcji, które przyjmują argumenty ciągów: wąskie (ANSI) i szerokie (Unicode). Na przykład interfejs API systemu Windows zawiera następujące nazwy punktów wejścia dla MessageBox funkcji:

  • MessageBoxA

    Zapewnia formatowanie ANSI o znakach 1 bajtów, wyróżniające się znakiem "A" dołączonym do nazwy punktu wejścia. Wywołania do MessageBoxA zawsze przekształcają ciągi znaków w formacie ANSI.

  • MessageBoxW

    Zapewnia formatowanie Unicode o znakach 2 bajtów, wyróżniające się znakiem "W" dołączonym do nazwy punktu wejścia. Wywołania do MessageBoxW zawsze serializują ciągi znakowe w formacie Unicode.

Marshallowanie ciągów i dopasowywanie nazw

Pole CharSet akceptuje następujące wartości:

Ansi (wartość domyślna)

  • Marshalling ciągów znaków

    Platforma wywołuje ciągi marshals z formatu zarządzanego (Unicode) do formatu ANSI.

  • Porównywanie nazw

    Gdy pole DllImportAttribute.ExactSpelling ma wartość true, co jest ustawieniem domyślnym w Visual Basic, platforma wywołuje wyszukiwanie tylko dla określonej nazwy. Jeśli na przykład określisz element MessageBox, platforma wywołuje wyszukiwanie MessageBox i kończy się niepowodzeniem, gdy nie może zlokalizować dokładnej pisowni.

    Gdy pole ExactSpelling ma wartość false, ponieważ tak jest domyślnie w językach C++ i C#, platforma wywołuje wyszukiwanie najpierw niemanglowanego aliasu (MessageBox), a następnie nazwy manglowanej (MessageBoxA), jeśli nie można odnaleźć niemanglowanego aliasu. Zwróć uwagę, że zachowanie dopasowywania nazw ANSI różni się od zachowania dopasowania nazw Unicode.

Unicode

  • Marshalling ciągów znaków

    Platforma kopiuje ciągi znaków z ich zarządzanego formatu (Unicode) do formatu Unicode.

  • Porównywanie nazw

    Gdy pole ExactSpelling ma wartość true, co jest ustawieniem domyślnym w Visual Basic, platforma wywołuje wyszukiwanie tylko dla określonej nazwy. Jeśli na przykład określisz element MessageBox, platforma wywołuje wyszukiwanie MessageBox i kończy się niepowodzeniem, jeśli nie może zlokalizować dokładnej pisowni.

    Gdy pole ma wartość ExactSpelling, ponieważ jest to domyślne w językach C++ i C#, platforma najpierw wyszukuje zniekształconą nazwę (false), a następnie niezmieniony alias (MessageBox), jeśli zniekształcona nazwa nie zostanie znaleziona. Zwróć uwagę, że zachowanie dopasowywania nazw Unicode różni się od zachowania dopasowania nazw ANSI.

Auto

  • Platforma wywołująca wybiera między formatami ANSI i Unicode podczas działania, w oparciu o platformę docelową.

Określanie zestawu znaków w Visual Basic

Zachowanie zestawu znaków w języku Visual Basic można określić, dodając Ansi słowo kluczowe, Unicode lub Auto do instrukcji deklaracji. W przypadku pominięcia słowa kluczowego zestawu znaków, pole DllImportAttribute.CharSet zostanie domyślnie ustawione na zestaw znaków ANSI.

Poniższy przykład deklaruje MessageBox funkcję trzy razy, za każdym razem z innym zachowaniem zestawu znaków. Pierwsza instrukcja pomija słowo kluczowe zestawu znaków, więc zestaw znaków domyślnie ustawia się na ANSI. Drugie i trzecie instrukcje jawnie określają zestaw znaków ze słowem kluczowym.

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

Określanie zestawu znaków w językach C# i C++

Pole DllImportAttribute.CharSet identyfikuje podstawowy zestaw znaków jako ANSI lub Unicode. Zestaw znaków określa sposób, w jaki argumenty ciągów do metody powinny być przekazywane. Użyj jednej z następujących formularzy, aby wskazać zestaw znaków:

[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)]

W poniższym przykładzie przedstawiono trzy zarządzane definicje MessageBox funkcji przypisane do określenia zestawu znaków. W pierwszej definicji, w wyniku pominięcia, pole CharSet domyślnie ustawia zestaw znaków ANSI.

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

Zobacz także