Specificare un set di caratteri

Il campo DllImportAttribute.CharSet controlla il marshalling delle stringhe e determina in che modo la funzionalità platform invoke trova i nomi di funzione in una DLL. Questo argomento descrive entrambi i comportamenti.

Alcune API esportano due versioni delle funzioni che accettano argomenti stringa: narrow (ANSI) e wide (Unicode). L'API Windows, ad esempio, include i seguenti nomi di punto di ingresso per la funzione MessageBox:

  • MessageBoxA

    Fornisce la formattazione ANSI dei caratteri a 1 byte, con l'aggiunta di "A" al nome del punto di ingresso per poterla distinguere. Le chiamate a MessageBoxA eseguono sempre il marshalling delle stringhe in formato ANSI.

  • MessageBoxW

    Fornisce la formattazione Unicode dei caratteri a 2 byte, con l'aggiunta di "W" al nome del punto di ingresso per poterla distinguere. Le chiamate a MessageBoxW eseguono sempre il marshalling delle stringhe in formato Unicode.

Marshalling delle stringhe e corrispondenza dei nomi

Il campo CharSet accetta i valori seguenti:

Ansi (valore predefinito)

  • Marshalling di stringhe

    La funzionalità platform invoke esegue il marshalling delle stringhe dal formato gestito (Unicode) al formato ANSI.

  • Corrispondenza dei nomi

    Quando il campo DllImportAttribute.ExactSpelling è true, come per impostazione predefinita in Visual Basic, platform invoke cerca solo il nome specificato. Ad esempio, se si specifica MessageBox, platform invoke cerca MessageBox e ha esito negativo quando non riesce a individuare la stringa con la stessa identica ortografia.

    Quando il campo ExactSpelling è false, come avviene per impostazione predefinita in C++ e C#, platform invoke cerca prima di tutto l'alias non modificato (MessageBox), poi il nome modificato (MessageBoxA) se non viene trovato l'alias non modificato. Si noti che il comportamento di corrispondenza dei nomi ANSI differisce dal comportamento di corrispondenza dei nomi Unicode.

Unicode

  • Marshalling di stringhe

    La funzionalità platform invoke copia le stringhe dal formato gestito (Unicode) al formato Unicode.

  • Corrispondenza dei nomi

    Quando il campo ExactSpelling è true, come per impostazione predefinita in Visual Basic, platform invoke cerca solo il nome specificato. Ad esempio, se si specifica MessageBox, platform invoke cerca MessageBox e ha esito negativo se non riesce a individuare la stringa con la stessa identica ortografia.

    Quando il campo ExactSpelling è false, come avviene per impostazione predefinita in C++ e C#, platform invoke cerca prima di tutto il nome modificato (MessageBoxW), poi l'alias non modificato (MessageBox) se non viene trovato il nome modificato. Si noti che il comportamento di corrispondenza dei nomi Unicode differisce dal comportamento di corrispondenza dei nomi ANSI.

Auto

  • La funzionalità platform invoke sceglie tra i formati ANSI e Unicode in fase di esecuzione, in base alla piattaforma di destinazione.

Specificare un set di caratteri in Visual Basic

È possibile specificare il comportamento per il set di caratteri in Visual Basic aggiungendo la parola chiave Ansi, Unicode o Auto nell'istruzione di dichiarazione. Se si omette la parola chiave per il set di caratteri, il campo DllImportAttribute.CharSet usa il set di caratteri ANSI per impostazione predefinita.

L'esempio seguente dichiara la funzione MessageBox tre volte, ogni volta con un diverso comportamento per il set di caratteri. La prima istruzione omette la parola chiave character-set, quindi il set di caratteri viene impostato per impostazione predefinita su ANSI. La seconda e la terza istruzione specificano in modo esplicito un set di caratteri con una parola chiave.

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

Specificare un set di caratteri in C# e C++

Il campo DllImportAttribute.CharSet identifica il set di caratteri sottostante come ANSI o Unicode. Il set di caratteri controlla la modalità di marshalling degli argomenti stringa in metodo. Usare una delle forme seguenti per indicare il set di caratteri:

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

L'esempio seguente mostra tre definizioni gestite della funzione MessageBox attribuite a un set di caratteri specifico. Nella prima definizione, con l'omissione, il campo CharSet usa per impostazione predefinita il set di caratteri 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);

Vedi anche