DllImportAttribute.CharSet フィールドは、文字列マーシャリングを制御し、プラットフォーム呼び出しで DLL 内の関数名を検索する方法を決定します。 このトピックでは、両方の動作について説明します。
一部の API では、文字列引数を受け取る関数の 2 つのバージョン (narrow (ANSI) と wide (Unicode) がエクスポートされます。 たとえば、Windows API には、 MessageBox 関数の次のエントリ ポイント名が含まれています。
MessageBoxA
エントリ ポイント名に付加された "A" で識別される 1 バイト文字の ANSI 書式を提供します。 MessageBoxA の呼び出しは、常に ANSI 形式で文字列をマーシャリングします。
MessageBoxW
エントリ ポイント名に追加された "W" で識別される 2 バイト文字の Unicode 書式を提供します。 MessageBoxW の呼び出しでは、常に Unicode 形式で文字列がマーシャリングされます。
文字列のマーシャリングと名前の一致
CharSet
フィールドには、次の値を指定できます。
Ansi (既定値)
文字列のマーシャリング
プラットフォームは、マネージド形式 (Unicode) から ANSI 形式へのマーシャリング文字列を呼び出します。
名前の一致
DllImportAttribute.ExactSpelling フィールドが Visual Basic の既定で
true
されている場合、プラットフォーム呼び出しでは指定した名前のみが検索されます。 たとえば、 MessageBox を指定した場合、プラットフォームは MessageBox の検索を呼び出し、正確なスペルが見つからない場合は失敗します。ExactSpelling
フィールドが C++ および C# で既定でfalse
されている場合、プラットフォーム呼び出しでは、未管理のエイリアスが見つからない場合は、最初に管理されていないエイリアス (MessageBox)、次にマングルされた名前 (MessageBoxA) が検索されます。 ANSI の名前一致動作は、Unicode の名前照合動作とは異なる点に注意してください。
文字列のマーシャリング
プラットフォーム呼び出しでは、文字列がマネージド形式 (Unicode) から Unicode 形式にコピーされます。
名前の一致
ExactSpelling
フィールドが Visual Basic の既定でtrue
されている場合、プラットフォーム呼び出しでは指定した名前のみが検索されます。 たとえば、 MessageBox を指定した場合、プラットフォームは MessageBox の検索を呼び出し、正確なスペルが見つからない場合は失敗します。ExactSpelling
フィールドが C++ および C# で既定でfalse
されている場合、プラットフォーム呼び出しでは、まずマングルされた名前 (MessageBoxW) を検索し、マングルされた名前が見つからない場合は、マングルされていないエイリアス (MessageBox) を検索します。 Unicode の名前一致動作は、ANSI の名前一致動作とは異なる点に注意してください。
- プラットフォーム呼び出しでは、ターゲット プラットフォームに基づいて、実行時に ANSI 形式と Unicode 形式を選択します。
Visual Basic で文字セットを指定する
Visual Basic では、 Ansi
、 Unicode
、または Auto
キーワードを宣言ステートメントに追加することで、文字セットの動作を指定できます。 文字セット キーワードを省略すると、 DllImportAttribute.CharSet フィールドの既定値は ANSI 文字セットになります。
次の例では、 MessageBox 関数を 3 回宣言します。そのたびに、文字セットの動作が異なります。 最初のステートメントでは文字セット キーワードが省略されているため、文字セットは既定で ANSI に設定されます。 2 番目と 3 番目のステートメントでは、キーワードを使用して文字セットを明示的に指定します。
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
C# および C++ で文字セットを指定する
DllImportAttribute.CharSet フィールドは、基になる文字セットを ANSI または Unicode として識別します。 文字セットは、メソッドの文字列引数をマーシャリングする方法を制御します。 文字セットを示すには、次のいずれかの形式を使用します。
[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)]
次の例は、文字セットを指定するために属性付けされた MessageBox 関数の 3 つのマネージド定義を示しています。 最初の定義では、省略により、 CharSet
フィールドの既定値は 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);
こちらも参照ください
.NET