文字列に対する既定のマーシャリングDefault Marshaling for Strings

System.StringSystem.Text.StringBuilder クラスのマーシャリング動作は類似しています。Both the System.String and System.Text.StringBuilder classes have similar marshaling behavior.

文字列は、COM スタイル BSTR 型または null で終わる文字列 (null 文字で終わる文字配列) としてマーシャリングされます。Strings are marshaled as a COM-style BSTR type or as a null-terminated string (a character array that ends with a null character). 文字列内の文字は、Unicode (Windows システムでの既定値) または ANSI としてマーシャリングすることができます。The characters within the string can be marshaled as Unicode (the default on Windows systems) or ANSI.

このトピックでは、文字列型のマーシャリングに関する以下の情報を示します。This topic provides the following information on marshaling string types:

インターフェイスで使用される文字列Strings Used in Interfaces

次の表は、アンマネージ コードへのメソッド引数としてマーシャリングするときの、文字列データ型のマーシャリングのオプションを示しています。The following table shows the marshaling options for the string data type when marshaled as a method argument to unmanaged code. MarshalAsAttribute 属性は、COM インターフェイスへの文字列をマーシャリングする UnmanagedType 列挙値を提供します。The MarshalAsAttribute attribute provides several UnmanagedType enumeration values to marshal strings to COM interfaces.

列挙型Enumeration type アンマネージ形式の説明Description of unmanaged format
UnmanagedType.BStr (既定値)UnmanagedType.BStr (default) 長さと Unicode 文字がプレフィックスされた COM スタイル BSTRA COM-style BSTR with a prefixed length and Unicode characters.
UnmanagedType.LPStr ANSI 文字の null で終わる配列へのポインター。A pointer to a null-terminated array of ANSI characters.
UnmanagedType.LPWStr Unicode 文字の null で終わる配列へのポインター。A pointer to a null-terminated array of Unicode characters.

この表は文字列に適用されます。This table applies to strings. ただし、StringBuilder の場合、許可される唯一のオプションは UnmanagedType.LPStrUnmanagedType.LPWStrです。However, for StringBuilder, the only options allowed are UnmanagedType.LPStr and UnmanagedType.LPWStr.

以下の例では、IStringWorker インターフェイスで宣言された文字列を示します。The following example shows strings declared in the IStringWorker interface.

public interface IStringWorker {  
void PassString1(String s);  
void PassString2([MarshalAs(UnmanagedType.BStr)]String s);  
void PassString3([MarshalAs(UnmanagedType.LPStr)]String s);  
void PassString4([MarshalAs(UnmanagedType.LPWStr)]String s);  
void PassStringRef1(ref String s);  
void PassStringRef2([MarshalAs(UnmanagedType.BStr)]ref String s);  
void PassStringRef3([MarshalAs(UnmanagedType.LPStr)]ref String s);  
void PassStringRef4([MarshalAs(UnmanagedType.LPWStr)]ref String s);  
);

以下の例では、タイプ ライブラリに記述された対応するインターフェイスを示します。The following example shows the corresponding interface described in a type library.

[…]  
interface IStringWorker : IDispatch {  
HRESULT PassString1([in] BSTR s);  
HRESULT PassString2([in] BSTR s);  
HRESULT PassString3([in] LPStr s);  
HRESULT PassString4([in] LPWStr s);  
HRESULT PassStringRef1([in, out] BSTR *s);  
HRESULT PassStringRef2([in, out] BSTR *s);  
HRESULT PassStringRef3([in, out] LPStr *s);  
HRESULT PassStringRef4([in, out] LPWStr *s);  
);

プラットフォーム呼び出しで使用される文字列Strings Used in Platform Invoke

プラットフォーム呼び出しは、文字列の引数を、.NET Framework 形式 (Unicode) から、プラットフォーム アンマネージ形式に変換してコピーします。Platform invoke copies string arguments, converting from the .NET Framework format (Unicode) to the platform unmanaged format. 文字列は不変であり、呼び出しが戻るときに、アンマネージ メモリから元のマネージ メモリにコピーされることはありません。Strings are immutable and are not copied back from unmanaged memory to managed memory when the call returns.

次の表は、文字列をプラットフォーム呼び出しのメソッド引数としてマーシャリングする際のマーシャリング オプションをリストしています。The following table lists the marshaling options for strings when marshaled as a method argument of a platform invoke call. MarshalAsAttribute 属性は、文字列をマーシャリングする UnmanagedType 列挙値を提供します。The MarshalAsAttribute attribute provides several UnmanagedType enumeration values to marshal strings.

列挙型Enumeration type アンマネージ形式の説明Description of unmanaged format
UnmanagedType.AnsiBStr 長さと ANSI 文字がプレフィックスされた COM スタイル BSTRA COM-style BSTR with a prefixed length and ANSI characters.
UnmanagedType.BStr 長さと Unicode 文字がプレフィックスされた COM スタイル BSTRA COM-style BSTR with a prefixed length and Unicode characters.
UnmanagedType.LPStr ANSI 文字の null で終わる配列へのポインター。A pointer to a null-terminated array of ANSI characters.
UnmanagedType.LPTStr プラットフォーム依存文字の null で終わる配列へのポインター。A pointer to a null-terminated array of platform-dependent characters.
UnmanagedType.LPWStr Unicode 文字の null で終わる配列へのポインター。A pointer to a null-terminated array of Unicode characters.
UnmanagedType.TBStr 長さとプラットフォーム依存文字がプレフィックスされた COM スタイル BSTRA COM-style BSTR with a prefixed length and platform-dependent characters.
VBByRefStr Visual Basic .NET で、アンマネージ コードの文字列を変更し、結果をマネージ コードに反映できるようにする値。A value that enables Visual Basic .NET to change a string in unmanaged code, and have the results reflected in managed code. この値は、プラットフォーム呼び出しでだけサポートされます。This value is supported only for platform invoke. これが、ByVal 文字列の Visual Basic での既定値です。This is default value in Visual Basic for ByVal strings.

この表は文字列に適用されます。This table applies to strings. ただし、StringBuilder の場合、許可される唯一のオプションは LPStrLPTStr、および LPWStr です。However, for StringBuilder, the only options allowed are LPStr, LPTStr, and LPWStr.

次の型定義は、プラットフォーム呼び出しで MarshalAsAttribute を使用するための正しい方法を示しています。The following type definition shows the correct use of MarshalAsAttribute for platform invoke calls.

Class StringLibAPI      
Public Declare Auto Sub PassLPStr Lib "StringLib.Dll" _  
(<MarshalAs(UnmanagedType.LPStr)> s As String)      
Public Declare Auto Sub PassLPWStr Lib "StringLib.Dll" _  
(<MarshalAs(UnmanagedType.LPWStr)> s As String)      
Public Declare Auto Sub PassLPTStr Lib "StringLib.Dll" _  
(<MarshalAs(UnmanagedType.LPTStr)> s As String)      
Public Declare Auto Sub PassBStr Lib "StringLib.Dll" _  
(<MarshalAs(UnmanagedType.BStr)> s As String)      
Public Declare Auto Sub PassAnsiBStr Lib "StringLib.Dll" _  
(<MarshalAs(UnmanagedType.AnsiBStr)> s As String)      
Public Declare Auto Sub PassTBStr Lib "StringLib.Dll" _  
(<MarshalAs(UnmanagedType.TBStr)> s As String)  
End Class  
class StringLibAPI {  
[DllImport("StringLib.Dll")]  
public static extern void PassLPStr([MarshalAs(UnmanagedType.LPStr)]  
String s);  
[DllImport("StringLib.Dll")]  
public static extern void   
PassLPWStr([MarshalAs(UnmanagedType.LPWStr)]String s);  
[DllImport("StringLib.Dll")]  
public static extern void   
PassLPTStr([MarshalAs(UnmanagedType.LPTStr)]String s);  
[DllImport("StringLib.Dll")]  
public static extern void PassBStr([MarshalAs(UnmanagedType.BStr)]  
String s);  
[DllImport("StringLib.Dll")]  
public static extern void   
PassAnsiBStr([MarshalAs(UnmanagedType.AnsiBStr)]String s);  
[DllImport("StringLib.Dll")]  
public static extern void PassTBStr([MarshalAs(UnmanagedType.TBStr)]  
String s);  
}  

構造体で使用される文字列Strings Used in Structures

文字列は構造体の有効なメンバーです。ただし、StringBuilder バッファーは構造体では無効です。Strings are valid members of structures; however, StringBuilder buffers are invalid in structures. 次の表は、型をフィールドとしてマーシャリングするときの、文字列データ型のマーシャリングのオプションを示しています。The following table shows the marshaling options for the string data type when the type is marshaled as a field. MarshalAsAttribute 属性は、文字列をフィールドにマーシャリングする UnmanagedType 列挙値を提供します。The MarshalAsAttribute attribute provides several UnmanagedType enumeration values to marshal strings to a field.

列挙型Enumeration type アンマネージ形式の説明Description of unmanaged format
UnmanagedType.BStr 長さと Unicode 文字がプレフィックスされた COM スタイル BSTRA COM-style BSTR with a prefixed length and Unicode characters.
UnmanagedType.LPStr ANSI 文字の null で終わる配列へのポインター。A pointer to a null-terminated array of ANSI characters.
UnmanagedType.LPTStr プラットフォーム依存文字の null で終わる配列へのポインター。A pointer to a null-terminated array of platform-dependent characters.
UnmanagedType.LPWStr Unicode 文字の null で終わる配列へのポインター。A pointer to a null-terminated array of Unicode characters.
UnmanagedType.ByValTStr 固定長の文字配列。配列の型は、包含構造体の文字セットによって決まります。A fixed-length array of characters; the array's type is determined by the character set of the containing structure.

ByValTStr 型は、構造体に定義されているインライン固定長文字配列で使用します。The ByValTStr type is used for inline, fixed-length character arrays that appear within a structure. その他の型は、文字列へのポインターを含む構造体に含まれている文字列参照に適用されます。Other types apply to string references contained within structures that contain pointers to strings.

包含構造体に適用される StructLayoutAttribute 属性の CharSet 引数によって、構造体内の文字列の文字形式が決まります。The CharSet argument of the StructLayoutAttribute attribute that is applied to the containing structure determines the character format of strings in structures. 以下の構造体の例には、文字列参照とインライン文字列、そして ANSI、Unicode、およびプラットフォーム依存文字が含まれています。The following example structures contain string references and inline strings, as well as ANSI, Unicode, and platform-dependent characters.

タイプ ライブラリの表現Type Library Representation

struct StringInfoA {  
   char *    f1;  
   char      f2[256];  
};  
struct StringInfoW {  
   WCHAR *   f1;  
   WCHAR     f2[256];  
   BSTR      f3;  
};  
struct StringInfoT {  
   TCHAR *   f1;  
   TCHAR     f2[256];  
};  

次のコード例は、MarshalAsAttribute 属性を使用して、同一の構造体を複数の異なる形式で定義する方法を示しています。The following code example shows how to use the MarshalAsAttribute attribute to define the same structure in different formats.

<StructLayout(LayoutKind.Sequential, CharSet := CharSet.Ansi)> _  
Structure StringInfoA  
<MarshalAs(UnmanagedType.LPStr)> Public f1 As String  
<MarshalAs(UnmanagedType.ByValTStr, SizeConst := 256)> _  
Public f2 As String  
End Structure  
<StructLayout(LayoutKind.Sequential, CharSet := CharSet.Unicode)> _  
Structure StringInfoW  
<MarshalAs(UnmanagedType.LPWStr)> Public f1 As String  
<MarshalAs(UnmanagedType.ByValTStr, SizeConst := 256)> _  
Public f2 As String  
<MarshalAs(UnmanagedType.BStr)> Public f3 As String  
End Structure  
<StructLayout(LayoutKind.Sequential, CharSet := CharSet.Auto)> _  
Structure StringInfoT  
<MarshalAs(UnmanagedType.LPTStr)> Public f1 As String  
<MarshalAs(UnmanagedType.ByValTStr, SizeConst := 256)> _  
Public f2 As String  
End Structure  
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]  
struct StringInfoA {  
   [MarshalAs(UnmanagedType.LPStr)] public String f1;  
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public String f2;  
}  
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]  
struct StringInfoW {  
   [MarshalAs(UnmanagedType.LPWStr)] public String f1;  
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public String f2;  
   [MarshalAs(UnmanagedType.BStr)] public String f3;  
}  
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]  
struct StringInfoT {  
   [MarshalAs(UnmanagedType.LPTStr)] public String f1;  
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public String f2;  
}  

固定長文字列バッファーFixed-Length String Buffers

状況によっては、固定長の文字列バッファーを、操作するためにアンマネージ コードに渡す必要があります。In some circumstances, a fixed-length character buffer must be passed into unmanaged code to be manipulated. この場合、呼び出し先は渡されたバッファーの内容を修正できないので、単に文字列を渡すだけでは不十分です。Simply passing a string does not work in this case because the callee cannot modify the contents of the passed buffer. 文字列が参照によって渡された場合でも、バッファーを特定のサイズに初期化する方法はありません。Even if the string is passed by reference, there is no way to initialize the buffer to a given size.

この解決策は、StringBuilder バッファーを文字列ではなく引数として渡すことです。The solution is to pass a StringBuilder buffer as the argument instead of a string. 呼び出し先は、StringBuilder の容量を超えない範囲で、StringBuilder を逆参照したり変更したりすることができます。A StringBuilder can be dereferenced and modified by the callee, provided it does not exceed the capacity of the StringBuilder. また、固定長に初期化することもできます。It can also be initialized to a fixed length. たとえば、StringBuilder バッファーを初期化してその容量を N にする場合、マーシャラーは (N+1) 文字のサイズのバッファーを提供します。For example, if you initialize a StringBuilder buffer to a capacity of N, the marshaler provides a buffer of size (N+1) characters. +1 は、アンマネージ文字列に null 終了文字があることをしめしています。StringBuilder にはそれがありません。The +1 accounts for the fact that the unmanaged string has a null terminator while StringBuilder does not.

たとえば、Microsoft Win32 API GetWindowText (Windows.h に定義されている) 関数は、固定長の文字バッファーを操作するアンマネージ コードを渡す必要があります。For example, the Microsoft Win32 API GetWindowText function (defined in Windows.h) is a fixed-length character buffer that must be passed into unmanaged code to be manipulated. LpString は、呼び出し元が割り当てたサイズ nMaxCount のバッファーを示します。LpString points to a caller-allocated buffer of size nMaxCount. 呼び出し元は、バッファーを割り当てて、nMaxCount 引数を割り当てられたバッファーのサイズに設定することが期待されています。The caller is expected to allocate the buffer and set the nMaxCount argument to the size of the allocated buffer. 次のコードは、Windows.h で定義されている GetWindowText 関数宣言を示しています。The following code shows the GetWindowText function declaration as defined in Windows.h.

int GetWindowText(  
HWND hWnd,        // Handle to window or control.  
LPTStr lpString,  // Text buffer.  
int nMaxCount     // Maximum number of characters to copy.  
);  

呼び出し先は、StringBuilder の容量を超えない範囲で、StringBuilder を逆参照したり変更したりすることができます。A StringBuilder can be dereferenced and modified by the callee, provided it does not exceed the capacity of the StringBuilder. 次のコード例は、StringBuilder を固定長に初期化する方法を示しています。The following code example demonstrates how StringBuilder can be initialized to a fixed length.

Public Class Win32API  
Public Declare Auto Sub GetWindowText Lib "User32.Dll" _  
(h As Integer, s As StringBuilder, nMaxCount As Integer)  
End Class  
Public Class Window  
   Friend h As Integer ' Friend handle to Window.  
   Public Function GetText() As String  
      Dim sb As New StringBuilder(256)  
      Win32API.GetWindowText(h, sb, sb.Capacity + 1)  
   Return sb.ToString()  
   End Function  
End Class  
public class Win32API {  
[DllImport("User32.Dll")]  
public static extern void GetWindowText(int h, StringBuilder s,   
int nMaxCount);  
}  
public class Window {  
   internal int h;        // Internal handle to Window.  
   public String GetText() {  
      StringBuilder sb = new StringBuilder(256);  
      Win32API.GetWindowText(h, sb, sb.Capacity + 1);  
   return sb.ToString();  
   }  
}  

参照See Also

既定のマーシャリング動作Default Marshaling Behavior
Blittable 型と非 Blittable 型Blittable and Non-Blittable Types
方向属性Directional Attributes
コピーと固定Copying and Pinning