Specifica di un set di caratteri
Il campo DllImportAttribute.CharSet consente di controllare il marshalling delle stringhe e di determinare la modalità con cui vengono trovati i nomi di funzione in una DLL mediante pInvoke. In questo argomento vengono descritte entrambe le funzionalità.
Alcune API esportano due diverse versioni di ciascuna funzione che accetta argomenti stringa: una piccola (ANSI) e una grande (Unicode). L'API Win32 include ad esempio la funzione MessageBox con i seguenti nomi di punto di ingresso:
MessageBoxA
Fornisce la formattazione ANSI con caratteri a byte singolo, che si distingue per il suffisso "A" aggiunto al nome del punto di ingresso. Con le chiamate a MessageBoxA viene sempre eseguito il marshalling delle stringhe in formato ANSI, come avviene di solito nelle piattaforme Windows 95 e Windows 98.
MessageBoxW
Fornisce la formattazione Unicode con caratteri a byte doppio, che si distingue per il suffisso "W" aggiunto al nome del punto di ingresso. Con le chiamate a MessageBoxW viene sempre eseguito il marshalling delle stringhe in formato Unicode, come avviene di solito nelle piattaforme Windows NT, Windows 2000 e Windows XP.
Marshalling delle stringhe e corrispondenza dei nomi
Il campo CharSet accetta i seguenti valori:
CharSet.Ansi (valore predefinito)
Marshalling delle stringhe
Platform invoke effettua il marshalling delle stringhe dal formato gestito (Unicode) al formato ANSI.
Corrispondenza dei nomi
Quando il campo DllImportAttribute.ExactSpelling è impostato su true, ovvero l'impostazione predefinita in Visual Basic 2005, con pInvoke viene cercato soltanto il nome specificato. Se ad esempio si specifica MessageBox, con platform invoke verrà cercato MessageBox e l'operazione avrà esito negativo in mancanza di un'esatta corrispondenza ortografica.
Quando il campo ExactSpelling è impostato su false (impostazione predefinita in C++ e C#), con platform invoke viene cercato innanzitutto l'alias non modificato (MessageBox) e successivamente, in caso di esito negativo, viene cercato il nome modificato (MessageBoxA). Si noti che il criterio adottato per la corrispondenza dei nomi ANSI differisce da quello adottato per la corrispondenza dei nomi Unicode.
CharSet.Unicode
Marshalling delle stringhe
Platform invoke copia le stringhe dal relativo formato gestito (Unicode) al formato Unicode.
Corrispondenza dei nomi
Quando il campo ExactSpelling è impostato su true, ovvero l'impostazione predefinita in Visual Basic 2005, con platform invoke viene cercato soltanto il nome specificato. Se ad esempio si specifica MessageBox, con platform invoke verrà cercato MessageBox e l'operazione avrà esito negativo in mancanza di un'esatta corrispondenza ortografica.
Quando il campo ExactSpelling è impostato su false (impostazione predefinita in C++ e C#), con platform invoke viene cercato innanzitutto il nome modificato (MessageBoxW) e successivamente, in caso di esito negativo, viene cercato l'alias non modificato (MessageBox). Si noti che il criterio adottato per la corrispondenza dei nomi Unicode differisce da quello adottato per la corrispondenza dei nomi ANSI.
CharSet.Auto
- In platform invoke, la scelta tra i formati ANSI e Unicode viene effettuata in fase di esecuzione, in base al sistema operativo di destinazione.
Specifica di un set di caratteri in Visual Basic
Nell'esempio riportato di seguito la funzione MessageBox viene dichiarata tre volte, ogni volta con un set di caratteri diverso. In Visual Basic è possibile specificare il comportamento dei set di caratteri aggiungendo la parola chiave Ansi, Unicode o Auto all'istruzione di dichiarazione.
Se si omette la parola chiave che specifica il set di caratteri, come avviene nella prima istruzione di dichiarazione, nel campo DllImportAttribute.CharSet verrà utilizzato per impostazione predefinita il set di caratteri ANSI. La seconda e la terza istruzione dell'esempio specificano esplicitamente un set di caratteri utilizzando una parola chiave.
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
Specifica di un set di caratteri in C# e in C++
Il campo DllImportAttribute.CharSet identifica il set di caratteri sottostante come ANSI o Unicode. Il set di caratteri controlla il modo in cui deve essere effettuato il marshalling degli argomenti stringa passati a un metodo. Per specificare il set di caratteri, utilizzare una delle seguenti forme:
[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)]
Nell'esempio riportato di seguito vengono illustrate tre definizioni gestite della funzione MessageBox dotate di attributi che specificano un determinato set di caratteri. Nella prima definizione, l'omissione del campo CharSet ne determina l'impostazione sul set di caratteri ANSI predefinito.
[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);
Vedere anche
Riferimenti
Concetti
Creazione di prototipi nel codice gestito