Microsoft KB Archive/317007

= BUG: TypeLoadException Is Generated Instead of MarshalDirectiveException =

Article ID: 317007

Article Last Modified on 5/17/2007

-

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(&quot;msvcrt.dll&quot;, EntryPoint=&quot;puts&quot;)] 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(&quot;\nShould never get here&quot;); Console.WriteLine(&quot;No Exception!&quot;); }       catch( MarshalDirectiveException e ) {           Console.WriteLine(&quot;\nputs_In case threw expected exception&quot;); Console.WriteLine(e.ToString + &quot;\n&quot;); }       catch( Exception e ) {           retVal = 0; Console.WriteLine(&quot;\nUnexpected Exception!&quot;); Console.WriteLine(e.ToString + &quot;\n&quot;); }

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

