BUG: StringBuilder Field in a Structure Cannot Be Marshaled Properly

Article translations Article translations
Article ID: 327109 - View products that this article applies to.
This article was previously published under Q327109
Expand all | Collapse all


If you marshal a structure that contains a StringBuilder field to an unmanaged function, the StringBuilder field is not marshaled correctly.


If you must initialize a buffer to some value before you pass to an unmanaged function, use one of the following workarounds:
  • Use the StringBuilder class, and apply to ANSI and Unicode strings. For example:
    StringBuilder buffer = new StringBuilder("content", 100); 
    buffer.Append('*', buffer.Capacity - 8); //add anything to the end
    MyStrStruct mss;
    mss.buffer = buffer.ToString();
    mss.size = mss.buffer.Length;
    Win32.TestStringInStruct(ref mss); // call unmanaged function
  • Use the Marshal class, and apply only to Unicode strings. For example:
    IntPtr pMem = Marshal.AllocCoTaskMem(100); 
    String inString = "content";
    Marshal.Copy(inString.ToCharArray(), 0, pMem, inString.Length);
    MyStrStruct mss;
    mss.buffer = pMem;
    mss.size = 100;
    Win32.TestStringInStruct(ref mss); // call unmanaged function
    String outString = Marshal.PtrToStringAuto(mss.buffer); 


Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.


To reproduce this problem, use the following code:
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace Test
	public struct STARTUPINFO 
		public Int32 cb;
		public StringBuilder lpReserved;
		public StringBuilder lpDesktop;
		public StringBuilder lpTitle;
		public Int32 dwX;
		public Int32 dwY;
		public Int32 dwXSize;
		public Int32 dwYSize;
		public Int32 dwXCountChars;
		public Int32 dwYCountChars;
		public Int32 dwFillAttribute;
		public Int32 dwFlags;
		public Int16 wShowWindow;
		public Int16 cbReserved2;
		public IntPtr lpReserved2;
		public IntPtr hStdInput;
		public IntPtr hStdOutput;
		public IntPtr hStdError;

	Original unmanaged structure:
	typedef struct _STARTUPINFO 
		DWORD   cb; 
		LPTSTR  lpReserved; 
		LPTSTR  lpDesktop; 
		LPTSTR  lpTitle; 
		DWORD   dwX; 
		DWORD   dwY; 
		DWORD   dwXSize; 
		DWORD   dwYSize; 
		DWORD   dwXCountChars; 
		DWORD   dwYCountChars; 
		DWORD   dwFillAttribute; 
		DWORD   dwFlags; 
		WORD    wShowWindow; 
		WORD    cbReserved2; 
		LPBYTE  lpReserved2; 
		HANDLE  hStdInput; 
		HANDLE  hStdOutput; 
		HANDLE  hStdError; 

	class TestAPI
		public static extern void GetStartupInfo(ref STARTUPINFO lpStartupInfo);

		static void Main(string[] args)
			STARTUPINFO startinfo = new STARTUPINFO();
			startinfo.lpReserved = new StringBuilder(256);
			startinfo.lpDesktop = new StringBuilder(256);
			startinfo.lpTitle = new StringBuilder(256);
			GetStartupInfo(ref startinfo);
If you compile and run this code, you receive a System.TypeLoadException exception, which contains the following information:
Marshaler restriction: StringBuilders can not be used in structure fields. The same effect can usually be achieved by using a String field and preinitializing it to a string with length matching the length of the appropriate buffer.


Article ID: 327109 - Last Review: February 23, 2007 - Revision: 2.6
  • Microsoft .NET Framework 1.0
  • Microsoft .NET Framework 1.1
kbbug kbcominterop kbnofix KB327109

Give Feedback


Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com