文字セットを指定する
DllImportAttribute.CharSet フィールドは文字列のマーシャリングを制御し、DLL の関数名をプラットフォーム呼び出しが見つけるしくみを決定します。 このトピックでは、両方の動作について説明します。
一部の API は、文字列引数、ナロー (ANSI) とワイド (Unicode) を受け取る 2 種類の関数をエクスポートします。 たとえば、Windows API には、MessageBox 関数の次のエントリ ポイント名が含まれています。
MessageBoxA
1 バイト文字の ANSI 書式設定を提供します。エントリ ポイント名に "A" が追加されます。 MessageBoxA を呼び出すと、常に ANSI 形式で文字列がマーシャリングされます。
MessageBoxW
2 バイト文字の Unicode 書式設定を提供します。エントリ ポイント名に "W" が追加されます。 MessageBoxW を呼び出すと、常に Unicode 形式で文字列がマーシャリングされます。
文字列のマーシャリングと名前の一致
CharSet
フィールドは次の値を受け取ります。
Ansi (既定値)
文字列のマーシャリング
プラットフォーム呼び出しは、その管理対象形式 (Unicode) から ANSI 形式に文字列をマーシャリングします。
名前の一致
DllImportAttribute.ExactSpelling フィールドが
true
の場合 (Visual Basic ではこれが既定値)、プラットフォーム呼び出しによって指定した名前のみが検索されます。 たとえば、MessageBox を指定した場合、プラットフォーム呼び出しは MessageBox を検索し、厳密に一致する綴りが見つからない場合、検索失敗となります。ExactSpelling
フィールドがfalse
のとき (C++ と C# で既定)、プラットフォーム呼び出しは最初に修飾なしのエイリアスを探し (ExactSpelling
)、見つからなければ、修飾ありの名前を探します (false
)。 ANSI の名前一致動作と Unicode の名前一致動作は異なることにご注意ください。
文字列のマーシャリング
プラットフォーム呼び出しは、その管理対象形式 (Unicode) から Unicode 形式に文字列をコピーします。
名前の一致
ExactSpelling
フィールドがtrue
の場合 (Visual Basic ではこれが既定値)、プラットフォーム呼び出しによって指定した名前のみが検索されます。 たとえば、MessageBox を指定した場合、プラットフォーム呼び出しは MessageBox を検索し、厳密に一致する綴りが見つからない場合、検索失敗となります。ExactSpelling
フィールドがfalse
のとき (C++ と C# で既定)、プラットフォーム呼び出しは最初に修飾ありの名前を探し (ExactSpelling
)、見つからなければ、修飾なしのエイリアスを探します (false
)。 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 を識別します。 この文字セットは、メソッドの文字列引数をマーシャリングする方法を制御します。 次の形式の 1 つを使用し、文字セットを指示します。
[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