文字セットの指定

DllImportAttribute.CharSet フィールドは、文字列のマーシャリングを制御したり、プラットフォーム呼び出しで DLL 内の関数名を検索する方法を決定したりします。このトピックでは、両方の動作について説明します。

一部の API は、文字列引数がナロー (ANSI) とワイド (Unicode) の 2 つの関数のバージョンをエクスポートします。たとえば Win32 API には、MessageBox 関数に対して次のエントリ ポイント名が含まれています。

  • MessageBoxA

    1 バイト文字 ANSI 形式を提供します。エントリ ポイント名の末尾の "A" で区別されます。MessageBoxA への呼び出しでは、Windows 95 プラットフォームおよび Windows 98 プラットフォームで通常行われているように、文字列は常に ANSI 形式でマーシャリングされます。

  • MessageBoxW

    2 バイト文字 Unicode 形式を提供します。エントリ ポイント名の末尾の "W" で区別されます。MessageBoxW への呼び出しでは、Windows NT、Windows 2000、Windows XP の各プラットフォームで通常行われているように、文字列は常に Unicode 形式でマーシャリングされます。

文字列のマーシャリングと名前の一致

CharSet フィールドは、次の値を受け入れます。

CharSet.Ansi (既定値)

  • 文字列のマーシャリング

    プラットフォーム呼び出しでは、文字列をマネージ形式 (Unicode) から ANSI 形式にマーシャリングします。

  • 名前の一致

    DllImportAttribute.ExactSpelling フィールドが true (Visual Basic 2005 の既定値) の場合、プラットフォーム呼び出しでは、指定した名前だけが検索されます。たとえば MessageBox と指定すると、プラットフォーム呼び出しでは MessageBox を検索し、正確に一致する名前が見つからない場合には失敗します。

    ExactSpelling フィールドが false (C++ および C# の既定値) の場合、プラットフォーム呼び出しでは、変形処理されていない名前 (MessageBox) を最初に検索し、それが見つからない場合には、変形処理された名前 (MessageBoxA) を検索します。名前の一致の動作は、ANSI と Unicode とでは異なります。

CharSet.Unicode

  • 文字列のマーシャリング

    プラットフォーム呼び出しでは、文字列をマネージ形式 (Unicode) から Unicode 形式にコピーします。

  • 名前の一致

    ExactSpelling フィールドが true (Visual Basic 2005 の既定値) の場合、プラットフォーム呼び出しでは、指定した名前だけが検索されます。たとえば MessageBox と指定すると、プラットフォーム呼び出しでは MessageBox を検索し、正確に一致する名前が見つからない場合には失敗します。

    ExactSpelling フィールドが false (C++ および C# の既定値) の場合、プラットフォーム呼び出しでは、変形処理された名前 (MessageBoxW) を最初に検索し、それが見つからない場合には、変形処理されていない名前 (MessageBox) を検索します。名前の一致の動作は、Unicode と ANSI とでは異なります。

CharSet.Auto

  • プラットフォーム呼び出しでは、対象となるプラットフォームに応じて、実行時に ANSI 形式または Unicode 形式を選択します。

Visual Basic での文字セットの指定

MessageBox 関数を 3 回宣言し、そのそれぞれで異なる文字セットを指定する例を次に示します。Visual Basic で文字セットを指定するには、宣言ステートメントに AnsiUnicode、または Auto キーワードを追加します。

この例の最初の宣言ステートメントのように、文字セット キーワードを省略すると、DllImportAttribute.CharSet フィールドは既定により ANSI 文字セットに設定されます。この例の第 2 および第 3 のステートメントでは、キーワードを使用して明示的に文字セットを指定しています。

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

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 文字セットに設定されます。

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

参照

関連項目

DllImportAttribute Class

概念

マネージ コードでのプロトタイプの作成
プラットフォーム呼び出しの例

その他の技術情報

プラットフォーム呼び出しによるデータのマーシャリング