Especificación de un juego de caracteres
El campo DllImportAttribute.CharSet controla la serialización de cadenas y determina cómo la invocación de plataforma busca nombres de función en un archivo DLL. En este tema se describen ambos comportamientos.
Algunas API exportan dos versiones de las funciones que toman argumentos de cadena: la versión estrecha (ANSI) y la versión ancha (Unicode). La API de Windows, por ejemplo, incluye los siguientes nombres de punto de entrada para la función MessageBox:
MessageBoxA
Proporciona el formato ANSI de caracteres de 1 byte, que se distingue por una "A" anexada al nombre del punto de entrada. Las llamadas a MessageBoxA siempre serializan las cadenas en formato ANSI.
MessageBoxW
Proporciona el formato Unicode de caracteres de 2 bytes, que se distingue por una "W" anexada al nombre del punto de entrada. Las llamadas a MessageBoxW siempre serializan las cadenas en formato Unicode.
Serialización de cadenas y coincidencia de nombres
El campo CharSet
acepta los valores siguientes:
Ansi (valor predeterminado)
Serialización de cadenas
La invocación de plataforma serializa las cadenas del formato administrado (Unicode) al formato ANSI.
Coincidencia de nombres
Cuando el campo DllImportAttribute.ExactSpelling es
true
, como sucede de forma predeterminada en Visual Basic, la invocación de plataforma solo busca el nombre que se especifique. Por ejemplo, si especifica MessageBox, la invocación de plataforma busca MessageBox y se produce un error si no encuentra el término exacto.Si el campo
ExactSpelling
esfalse
, como sucede de forma predeterminada en C++ y C#, la invocación de plataforma busca primero el alias no alterado (MessageBox) y, luego, el nombre alterado (MessageBoxA) en el caso de que no se encuentre el alias no alterado. Tenga en cuenta que el comportamiento de la coincidencia de nombres en formato ANSI difiere del comportamiento de la coincidencia de nombres en formato Unicode.
Serialización de cadenas
La invocación de plataforma copia las cadenas del formato administrado (Unicode) al formato Unicode.
Coincidencia de nombres
Cuando el campo
ExactSpelling
estrue
, como sucede de forma predeterminada en Visual Basic, la invocación de plataforma solo busca el nombre que se especifique. Por ejemplo, si especifica MessageBox, la invocación de plataforma busca MessageBox y se produce un error si no encuentra el término exacto.Si el campo
ExactSpelling
esfalse
, como sucede de forma predeterminada en C++ y C#, la invocación de plataforma busca primero el alias alterado (MessageBoxW) y, luego, el nombre no alterado (MessageBox) en el caso de que no se encuentre el alias alterado. Tenga en cuenta que el comportamiento de la coincidencia de nombres en formato Unicode difiere del comportamiento de la coincidencia de nombres en formato ANSI.
- La invocación de plataforma elige entre los formatos ANSI y Unicode en tiempo de ejecución en función de la plataforma de destino.
Especificación de un juego de caracteres en Visual Basic
Puede especificar un comportamiento de juego de caracteres en Visual Basic si agrega la palabra clave Ansi
, Unicode
o Auto
a la instrucción de declaración. Si omite la palabra clave del juego de caracteres, el campo DllImportAttribute.CharSet establece como valor predeterminado el juego de caracteres ANSI.
En el ejemplo siguiente se declara la función MessageBox tres veces, cada una de ellas con un comportamiento de juego de caracteres diferente. La primera instrucción omite la palabra clave del juego de caracteres, por lo que tiene ANSI como valor predeterminado. En la segunda y tercera instrucciones se especifica explícitamente un juego de caracteres con una palabra clave.
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
Especificación de un juego de caracteres en C# y C++
El campo DllImportAttribute.CharSet identifica el juego de caracteres subyacente como ANSI o Unicode. El juego de caracteres controla cómo se deben serializar los argumentos de cadena para un método. Use uno de los formatos siguientes para indicar el juego de caracteres:
[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)]
En el ejemplo siguiente se muestran tres definiciones administradas de la función MessageBox con atributos para especificar un juego de caracteres. En la primera definición, debido a su omisión, el campo CharSet
establece como valor predeterminado el juego de caracteres 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);