BUG: TypeLoadException Is Generated Instead of MarshalDirectiveException (317007)



The information in this article applies to:

  • Microsoft .NET Framework 1.0
  • Microsoft .NET Framework 1.1

This article was previously published under Q317007

SYMPTOMS

Under some circumstances, a TypeLoadException exception is generated instead of a MarshalDirectiveException exception when you use P/Invoke.

STATUS

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

MORE INFORMATION

The MarshalAs attribute can be used to control marshalling behavior for non-blittable types in fields, parameters, or return types. If the MarshalAs attribute specifies an unmanaged type that is not a permitted unmanaged representation for the specified managed type, a MarshalDirectiveException exception is generated at run time when the P/Invoke call is made. If the MarshalAs directive is used for a class field, and it specifies an unsupported unmanaged representation, a TypeLoadException exception is generated instead. The following sample should generate a MarshalDirectiveException exception, indicating that a bool can only be paired with the Bool and VariantBool members of UnmanagedType.

Steps to Reproduce the Behavior

When you execute the following Microsoft Visual C# sample code, note that the generic Exception catch block is executed instead of the MarshalDirectiveException catch block.
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential)]
public class TestStruct
{
        //This is the incorrect MarshalAs directive. 
	[MarshalAs(UnmanagedType.ByValArray, ArraySubType=UnmanagedType.LPWStr, SizeConst=4)]
	public bool b;
}


public class Tester
{
	[DllImport("msvcrt.dll", EntryPoint="puts")]
	public static extern int puts_In(TestStruct ts);

	public static int Main()
	{
		int retVal = 0xAAAA; //Initializing to passing value.
		TestStruct ts = new TestStruct();
		ts.b = true;

		//testing puts_In
		try
		{
			puts_In(ts);
			retVal = 0;
		        Console.WriteLine("\nShould never get here");
			Console.WriteLine("No Exception!");
		}
		catch( MarshalDirectiveException e )
		{
			Console.WriteLine("\nputs_In case threw expected exception");
			Console.WriteLine(e.ToString() + "\n");	
		}
		catch( Exception e )
		{
			retVal = 0;
			Console.WriteLine("\nUnexpected Exception!"); 
			Console.WriteLine(e.ToString() + "\n");
		}

		Console.WriteLine((retVal==0xAAAA)?"PASSED!":"FAILED!");
		return retVal;
	}
}
				

REFERENCES

For more information, visit the following Microsoft Developer Network (MSDN) Web sites:

Modification Type:MajorLast Reviewed:1/19/2004
Keywords:kbbug KB317007