文字列に対する既定のマーシャリング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.

インターフェイスで使用される文字列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.

この表は String に適用されます。This table applies to String. StringBuilder の場合、許可される唯一のオプションは UnmanagedType.LPStrUnmanagedType.LPWStr です。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);
}
Public Interface IStringWorker
    Sub PassString1(s As String)
    Sub PassString2(<MarshalAs(UnmanagedType.BStr)> s As String)
    Sub PassString3(<MarshalAs(UnmanagedType.LPStr)> s As String)
    Sub PassString4(<MarshalAs(UnmanagedType.LPWStr)> s As String)
    Sub PassStringRef1(ByRef s As String)
    Sub PassStringRef2(<MarshalAs(UnmanagedType.BStr)> ByRef s As String)
    Sub PassStringRef3(<MarshalAs(UnmanagedType.LPStr)> ByRef s As String)
    Sub PassStringRef4(<MarshalAs(UnmanagedType.LPWStr)> ByRef s As String)
End Interface

以下の例では、タイプ ライブラリに記述された対応するインターフェイスを示します。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 (既定値)UnmanagedType.LPStr (default) 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.LPUTF8Str UTF-8 でエンコードされた文字の NULL で終わる配列へのポインター。A pointer to a null-terminated array of UTF-8 encoded 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 the default value in Visual Basic for ByVal strings.

この表は String に適用されます。This table applies to String. StringBuilder の場合、許可される唯一のオプションは LPStrLPTStr、および LPWStr です。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
{
    [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 PassLPUTF8Str([MarshalAs(UnmanagedType.LPUTF8Str)] 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);
}
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 PassLPUTF8Str Lib "StringLib.dll" (
        <MarshalAs(UnmanagedType.LPUTF8Str)> 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

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

文字列は構造体の有効なメンバーです。ただし、StringBuilder バッファーは構造体では無効です。Strings are valid members of structures; however, StringBuilder buffers are invalid in structures. 次の表は、型をフィールドとしてマーシャリングするときの、String データ型のマーシャリングのオプションを示しています。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 (既定値)UnmanagedType.LPStr (default) 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.LPUTF8Str UTF-8 でエンコードされた文字の NULL で終わる配列へのポインター。A pointer to a null-terminated array of UTF-8 encoded 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.

包含構造体に適用される StructLayoutAttributeCharSet 引数によって、構造体内の文字列の文字形式が決まります。The CharSet argument of the StructLayoutAttribute 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. タイプ ライブラリ内のこれらの構造体の表現を次の C++ コードに示します。The representation of these structures in a type library is shown in the following C++ code:

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 example shows how to use the MarshalAsAttribute to define the same structure in different formats.

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

固定長文字列バッファー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 バッファーを String ではなく引数として渡すことです。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.

たとえば、Windows GetWindowText API 関数 (winuser.h で定義されています) では、関数からウィンドウのテキストが出力される固定長の文字バッファーを呼び出し元が渡す必要があります。For example, the Windows GetWindowText API function (defined in winuser.h) requires that the caller pass a fixed-length character buffer to which the function writes the window's text. 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. 次の例は、winuser.h で定義されている GetWindowText 関数宣言を示しています。The following example shows the GetWindowText function declaration as defined in winuser.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.

using System;
using System.Runtime.InteropServices;
using System.Text;

internal static class NativeMethods
{
    [DllImport("User32.dll")]
    internal static extern void GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
}

public class Window
{
    internal IntPtr h;        // Internal handle to Window.
    public String GetText()
    {
        StringBuilder sb = new StringBuilder(256);
        NativeMethods.GetWindowText(h, sb, sb.Capacity + 1);
        return sb.ToString();
    }
}
Imports System.Text

Friend Class NativeMethods
    Friend Declare Auto Sub GetWindowText Lib "User32.dll" _
        (hWnd As IntPtr, lpString As StringBuilder, nMaxCount As Integer)
End Class

Public Class Window
    Friend h As IntPtr ' Friend handle to Window.
    Public Function GetText() As String
        Dim sb As New StringBuilder(256)
        NativeMethods.GetWindowText(h, sb, sb.Capacity + 1)
        Return sb.ToString()
   End Function
End Class

関連項目See also